iOS開發之設定介面的抽取

來源:互聯網
上載者:User

iOS開發之設定介面的抽取

那麼我們的設定介面到底要怎麼寫才能最方便使用呢?下面我就來說說我的想法。1.觀察原型圖2.找出相同的東西,目的是抽出一個基類別模組,只要我寫好了這個控制器,其它的介面全部都寫好了3.判斷是用純程式碼還是storyboard,如果介面的控制項位置都是固定,用storyboard。什麼時候用靜態儲存格:如果介面cell跟系統內建的cell完全差不多,就可以選擇靜態儲存格如果不相似:1.判斷其它cell是否全部差不多,如果全部差不多,可以使用靜態儲存格2.如果介面差別很大,就不使用靜態儲存格,就用代碼那麼下面我們就來抽取設定介面: 首先繼承UITableViewController寫一個BasicSettingViewController.h//這一組有多少行cell<SettingItem>@property (nonatomic, strong) NSMutableArray *groups;.m#import "BasicTableViewController.h"#import "GroupItem.h"#import "SettingItem.h"#import "BasicCell.h"@interface BasicTableViewController ()@end@implementation BasicTableViewController//讓這個類一初始化就是組樣式的- (instancetype)init {    return [self initWithStyle:UITableViewStyleGrouped];}- (void)viewDidLoad {    [super viewDidLoad];//設定tableView的一些基本資料    self.tableView.backgroundColor = [UIColor colorWithRed:211 green:211 blue:211 alpha:1];    self.tableView.sectionHeaderHeight = 10;    self.tableView.sectionFooterHeight = 0;    self.tableView.contentInset = UIEdgeInsetsMake(-25, 0, 0, 0);    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;}//一定要對組進行懶載入,不然的話,子類是沒有辦法初始化他的- (NSMutableArray *)groups {    if (!_groups) {        _groups = [NSMutableArray array];    }    return _groups;}#pragma mark - Table view data source//返回組數- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {#warning Incomplete implementation, return the number of sections    return self.groups.count;}//返回行數- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {#warning Incomplete implementation, return the number of rows    GroupItem *group = self.groups[section];    return group.items.count;}//初始化cell並給cell賦值- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    BasicCell *cell = [BasicCell cellWithTableView:tableView];    GroupItem *group = self.groups[indexPath.section];    SettingItem *item = group.items[indexPath.row];    cell.item = item;    [cell setIndexPath:indexPath rowCount:group.items.count];    return cell;}//返回腳部標題- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {    GroupItem *group = self.groups[section];    return group.footTitle;}//返回頭部標題- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {    GroupItem *group = self.groups[section];    return group.headTitle;}//當cell選中的時候執行該方法- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {    [tableView deselectRowAtIndexPath:indexPath animated:YES];    GroupItem *group = self.groups[indexPath.section];    SettingItem *item = group.items[indexPath.row];    if (item.destVc) {//如果有跳轉就執行跳轉        UIViewController *destVc = [[item.destVc alloc] init];        [self.navigationController pushViewController:destVc animated:YES];    }    if (item.option) {//哪個cell有事情就做事情(自己的事情自己幹)        item.option();    }}複製代碼設定組模型(基類):複製代碼@interface GroupItem : NSObject//每一組的行數@property (nonatomic, strong) NSArray *items;//頭標題@property (nonatomic, copy) NSString *headTitle;//腳標題@property (nonatomic, copy) NSString *footTitle;@end typedef void (^SettingItemOption) ();@interface SettingItem : NSObject//左邊神圖@property (nonatomic, strong) UIImage *image;//標題@property (nonatomic, copy) NSString *title;//子標題@property (nonatomic, copy) NSString *subTitle;@property (nonatomic, assign) Class destVc;//跳轉到目標控制器(最好不要用NSString)@property (nonatomic, copy) SettingItemOption option;//在ARC模型下只能使用copy,MRC可以使用copy或者strong,為了把他放到堆記憶體中,如果放在棧記憶體中會被釋放//提供兩個建立的item的方法+ (instancetype)itemWithTitle:(NSString *)title;+ (instancetype)itemWithTitle:(NSString *)title image:(UIImage *)image;@end 因為內容是根據模型的改變而改變,那麼我們就建立幾個模型(繼承於SettingItem):每個基類要是有自己特有的一些屬性也可以設定@interface ArrowItem : SettingItem@end@interface BadgeItem : SettingItem@property (nonatomic, copy) NSString *badgeValue;@end@interface SwitchItem : SettingItem@property (nonatomic, assign) BOOL isOn;//是否開啟@end@interface LabelItem : SettingItem@property (nonatomic, copy) NSString *text;//label上面的text@end@interface CheakItem : SettingItem@property (nonatomic, assign) BOOL isCheak;//是否打勾@end 設定的cell(基類):複製代碼@class SettingItem;@interface BasicCell : UITableViewCell//根據settingItem模型來顯示內容@property (nonatomic, strong) SettingItem *item;//給外部提供一個建立cell的方法+ (instancetype)cellWithTableView:(UITableView *)tableView;//設定每一組的背景圖片的方法- (void)setIndexPath:(NSIndexPath *)indexPath rowCount:(NSInteger)rowCount;@end @interface BasicCell ()//這裡一定要用strong,因為是加在視圖上面而不是加在contentView;//箭頭格式的cell@property (nonatomic, strong) UIImageView *arrowView;//開關格式的cell@property (nonatomic, strong) UISwitch *switchView;//打勾格式的cell@property (nonatomic, strong) UIImageView *cheakView;//label格式的cell@property (nonatomic, weak) UILabel *labelView;@end//不變形的展開圖片(一般要是寫項目最好寫成category)@implementation UIImage (Resizable)+ (UIImage *)resizableWithImageName:(NSString *)imageName {    UIImage *image = [UIImage imageNamed:imageName];    return [image stretchableImageWithLeftCapWidth:image.size.width/2 topCapHeight:image.size.height/2];}@end@implementation BasicCell#pragma mark - 對所有的控制項懶載入- (UIImageView *)arrowView{    if (_arrowView == nil) {        _arrowView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"common_icon_arrow"]];    }    return _arrowView;}- (UISwitch *)switchView{    if (_switchView == nil) {        _switchView = [[UISwitch alloc] init];        [_switchView addTarget:self action:@selector(switchChange:) forControlEvents:UIControlEventValueChanged];            }    return _switchView;}- (UIImageView *)cheakView{    if (_cheakView == nil) {        _cheakView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"common_icon_checkmark"]];    }    return _cheakView;}- (UILabel *)labelView {    if (!_labelView) {        UILabel *labelView = [[UILabel alloc] initWithFrame:self.bounds];        labelView.textAlignment = NSTextAlignmentCenter;        labelView.textColor = [UIColor redColor];        [self.contentView addSubview:labelView];        _labelView = labelView;    }    return _labelView;}#pragma mark - switchChange- (void)switchChange:(UISwitch *)switchView {    }- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {//只需要設定一次的東西最好放到這個方法中執行,因為這個方法只會在建立cell的時候執行一次,而不會每次給模型賦值的時候都會執行        self.detailTextLabel.font = [UIFont systemFontOfSize:14];        self.backgroundColor = [UIColor clearColor];        self.backgroundView = [[UIImageView alloc] init];        self.selectedBackgroundView = [[UIImageView alloc] init];    }    return self;}+ (instancetype)cellWithTableView:(UITableView *)tableView {    static NSString *ID = @"cell";    BasicCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    if (!cell) {        //這裡一定要用self        cell = [[self alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID];    }    return cell;}- (void)setItem:(SettingItem *)item {    _item = item;    //設定資料    [self setUpData];    //設定模型    [self setUpRightView];}- (void)setUpData {    self.textLabel.text = _item.title;    self.detailTextLabel.text = _item.subTitle;    self.imageView.image = _item.image;}- (void)setUpRightView {    if ([_item isKindOfClass:[ArrowItem class]]) {        //箭頭        self.accessoryView = self.arrowView;    }    else if ([_item isKindOfClass:[BadgeItem class]]) {        //badgeView        self.accessoryView = self.badgeView;    }    else if ([_item isKindOfClass:[SwitchItem class]]) {        //開關        self.accessoryView = self.switchView;    }    else if ([_item isKindOfClass:[LabelItem class]]) {        //Label        LabelItem *labelItem = (LabelItem *)_item;        UILabel *label = self.labelView;        label.text = labelItem.text;    }    else if ([_item isKindOfClass:[CheakItem class]]) {        //打勾        CheakItem *cheakItem = (CheakItem *)_item;        if (cheakItem.isCheak) {            self.accessoryView = self.cheakView;        }        else {            self.accessoryView = nil;        }    }    else {        [_labelView removeFromSuperview];        _labelView = nil;        self.accessoryView = nil;    }}- (void)setIndexPath:(NSIndexPath *)indexPath rowCount:(NSInteger)rowCount {    UIImageView *bgView = (UIImageView *)self.backgroundView;    UIImageView *selBgView = (UIImageView *)self.selectedBackgroundView;    if (rowCount == 1) { // 只有一行        bgView.image = [UIImage resizableWithImageName:@"common_card_background"];        selBgView.image = [UIImage resizableWithImageName:@"common_card_background_highlighted"];            }else if(indexPath.row == 0){ // 頂部cell        bgView.image = [UIImage resizableWithImageName:@"common_card_top_background"];        selBgView.image = [UIImage resizableWithImageName:@"common_card_top_background_highlighted"];            }else if (indexPath.row == rowCount - 1){ // 底部        bgView.image = [UIImage resizableWithImageName:@"common_card_bottom_background"];        selBgView.image = [UIImage resizableWithImageName:@"common_card_bottom_background_highlighted"];            }else{ // 中間        bgView.image = [UIImage resizableWithImageName:@"common_card_middle_background"];        selBgView.image = [UIImage resizableWithImageName:@"common_card_middle_background_highlighted"];    }}#pragma mark - 這裡寫才能置中對齊- (void)layoutSubviews {    [super layoutSubviews];    _labelView.frame = self.bounds;} 到此,所有的都已經抽出來了。你可能想問了那要麼是子類和父類長的很像但是卻不一樣怎麼辦?那麼就能用到OC中繼承的這個性質了,子類只要重寫一下父類的方法就可以了。隨便寫幾個控制器,繼承於BasicSettingViewController我的介面 - (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.    [self setUpNav];    [self setUpGroup0];    [self setUpGroup1];    [self setUpGroup2];    [self setUpGroup3];}- (void)setUpNav {    UIBarButtonItem *setting = [[UIBarButtonItem alloc] initWithTitle:@"設定" style:UIBarButtonItemStylePlain target:self action:@selector(setting)];    NSMutableDictionary *dict = [NSMutableDictionary dictionary];    dict[NSForegroundColorAttributeName] = [UIColor blackColor];    [setting setTitleTextAttributes:dict forState:UIControlStateNormal];    self.navigationItem.rightBarButtonItem = setting;}#pragma mark - 設定- (void)setting {    SettingViewController *setVc = [[SettingViewController alloc] init];    [self.navigationController pushViewController:setVc animated:YES];}- (void)setUpGroup0{    // 新的好友    ArrowItem *friend = [ArrowItem itemWithTitle:@"新的好友" image:[UIImage imageNamed:@"new_friend"]];        GroupItem *group = [[GroupItem alloc] init];    group.items = @[friend];    [self.groups addObject:group];}- (void)setUpGroup1{    // 我的相簿    ArrowItem *album = [ArrowItem itemWithTitle:@"我的相簿" image:[UIImage imageNamed:@"album"]];    album.subTitle = @"(12)";        // 我的收藏    ArrowItem *collect = [ArrowItem itemWithTitle:@"我的收藏" image:[UIImage imageNamed:@"collect"]];    collect.subTitle = @"(0)";        // 贊    ArrowItem *like = [ArrowItem itemWithTitle:@"贊" image:[UIImage imageNamed:@"like"]];    like.subTitle = @"(0)";    GroupItem *group = [[GroupItem alloc] init];    group.items = @[album,collect,like];    [self.groups addObject:group];}- (void)setUpGroup2{    // 微博支付    ArrowItem *pay = [ArrowItem itemWithTitle:@"微博支付" image:[UIImage imageNamed:@"pay"]];    // 個人化    ArrowItem *vip = [ArrowItem itemWithTitle:@"個人化" image:[UIImage imageNamed:@"vip"]];    vip.subTitle = @"微博來源、皮膚、封面圖";    GroupItem *group = [[GroupItem alloc] init];    group.items = @[pay,vip];    [self.groups addObject:group];}- (void)setUpGroup3{    // 我的二維碼    ArrowItem *card = [ArrowItem itemWithTitle:@"我的二維碼" image:[UIImage imageNamed:@"card"]];    // 草稿箱    ArrowItem *draft = [ArrowItem itemWithTitle:@"草稿箱" image:[UIImage imageNamed:@"draft"]];        GroupItem *group = [[GroupItem alloc] init];    group.items = @[card,draft];    [self.groups addObject:group];}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    ProfileCell *cell = [ProfileCell cellWithTableView:tableView];    GroupItem *group = self.groups[indexPath.section];    SettingItem *item = group.items[indexPath.row];    cell.item = item;    [cell setIndexPath:indexPath rowCount:group.items.count];    return cell;}複製代碼因為cell和父類不太一樣,所以cell要繼承於BasicCell重寫一下複製代碼- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {        self.detailTextLabel.font = [UIFont systemFontOfSize:12];    }    return self;}//一定要在這個方法中重寫,不然可能會沒用,這個是在載入完成即將顯示的時候調用,載入的frame是100%正確的- (void)layoutSubviews {    [super layoutSubviews];    CGRect frame = self.detailTextLabel.frame;    frame.origin.x = CGRectGetMaxX(self.textLabel.frame) + 5;    self.detailTextLabel.frame = frame;}  設定介面 - (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.        // 添加第0組    [self setUpGroup0];    // 添加第1組    [self setUpGroup1];    // 添加第2組    [self setUpGroup2];    // 添加第3組    [self setUpGroup3];}- (void)setUpGroup0{    // 帳號管理    ArrowItem *account = [ArrowItem itemWithTitle:@"帳號管理"];//    account.badgeValue = @"8";    GroupItem *group = [[GroupItem alloc] init];    group.items = @[account];    [self.groups addObject:group];}- (void)setUpGroup1{    // 提醒和通知    ArrowItem *notice = [ArrowItem itemWithTitle:@"我的相簿" ];    // 通用設定    ArrowItem *setting = [ArrowItem itemWithTitle:@"通用設定" ];    setting.destVc = [CommonViewController class];    // 隱私與安全    ArrowItem *secure = [ArrowItem itemWithTitle:@"隱私與安全" ];        GroupItem *group = [[GroupItem alloc] init];    group.items = @[notice,setting,secure];    [self.groups addObject:group];}- (void)setUpGroup2{    // 意見反饋    ArrowItem *suggest = [ArrowItem itemWithTitle:@"意見反饋" ];    // 關於微博    ArrowItem *about = [ArrowItem itemWithTitle:@"關於微博"];    GroupItem *group = [[GroupItem alloc] init];    group.items = @[suggest,about];    [self.groups addObject:group];}- (void)setUpGroup3{    // 帳號管理    LabelItem *layout = [[LabelItem alloc] init];    layout.text = @"退出當前帳號";        GroupItem *group = [[GroupItem alloc] init];    group.items = @[layout];    [self.groups addObject:group];} 通用設定介面 - (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.    // 添加第0組    [self setUpGroup0];    // 添加第1組    [self setUpGroup1];    // 添加第2組    [self setUpGroup2];    // 添加第3組    [self setUpGroup3];        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refresh:) name:@"FontSizeChangeNote" object:nil];}- (void)refresh:(NSNotification *)notification {    _fontSize.subTitle = notification.userInfo[FontSizeKey];    [self.tableView reloadData];}- (void)setUpGroup0{    // 閱讀模式    SettingItem *read = [SettingItem itemWithTitle:@"閱讀模式"];    read.subTitle = @"有圖模式";        // 字型大小    SettingItem *fontSize = [SettingItem itemWithTitle:@"字型大小"];    _fontSize = fontSize;    NSString *fontSizeStr =  [[NSUserDefaults standardUserDefaults] objectForKey:FontSizeKey];    if (fontSizeStr == nil) {        fontSizeStr = @"中";    }    fontSize.subTitle = fontSizeStr;    fontSize.destVc = [FontViewController class];        // 顯示備忘    SwitchItem *remark = [SwitchItem itemWithTitle:@"顯示備忘"];            GroupItem *group = [[GroupItem alloc] init];    group.items = @[read,fontSize,remark];    [self.groups addObject:group];}- (void)setUpGroup1{    // 圖片品質    ArrowItem *quality = [ArrowItem itemWithTitle:@"圖片品質" ];    GroupItem *group = [[GroupItem alloc] init];    group.items = @[quality];    [self.groups addObject:group];}- (void)setUpGroup2{    // 聲音    SwitchItem *sound = [SwitchItem itemWithTitle:@"聲音" ];        GroupItem *group = [[GroupItem alloc] init];    group.items = @[sound];    [self.groups addObject:group];}- (void)setUpGroup3{    // 多語言環境    SettingItem *language = [SettingItem itemWithTitle:@"多語言環境"];    language.subTitle = @"跟隨系統";    GroupItem *group = [[GroupItem alloc] init];    group.items = @[language];    [self.groups addObject:group];} 字型大小介面 - (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.    [self setUpGroup0];}- (void)setUpGroup0{    #pragma mark - 這種方法能消除block中的迴圈警告    // 大    __weak typeof(self) weakSelf = self;     CheakItem * __weak big = [CheakItem itemWithTitle:@"大"];    big.option = ^{        [weakSelf selItem:big];    };        // 中    CheakItem * __weak middle = [CheakItem itemWithTitle:@"中"];        middle.option = ^{        [weakSelf selItem:middle];    };    _selCheakItem = middle;    // 小    CheakItem * __weak small = [CheakItem itemWithTitle:@"小"];    small.option = ^{        [weakSelf selItem:small];    };    GroupItem *group = [[GroupItem alloc] init];    group.headTitle = @"上傳圖片品質";    group.items = @[big,middle,small];    [self.groups addObject:group];        // 預設選中item    [self setUpSelItem:middle];    }- (void)setUpSelItem:(CheakItem *)item{    NSString *fontSizeStr =  [[NSUserDefaults standardUserDefaults] objectForKey:FontSizeKey];    if (fontSizeStr == nil) {        [self selItem:item];        return;    }        for (GroupItem *group in self.groups) {        for (CheakItem *item in group.items) {            if ( [item.title isEqualToString:fontSizeStr]) {                [self selItem:item];            }                    }            }}- (void)selItem:(CheakItem *)item{    _selCheakItem.isCheak = NO;    item.isCheak = YES;    _selCheakItem = item;    [self.tableView reloadData];            // 儲存    [[NSUserDefaults standardUserDefaults] setObject:item.title forKey:FontSizeKey];    [[NSUserDefaults standardUserDefaults] synchronize];        // 發出通知    [[NSNotificationCenter defaultCenter] postNotificationName:@"FontSizeChangeNote" object:nil userInfo:@{FontSizeKey:item.title}];    }

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.