代码改变世界

论--如何通过代码解析plist文件创建对应的控制器,以及控制器中的控件

2016-03-03 19:36  菜鸟Alex  阅读(254)  评论(2编辑  收藏  举报
  • 通过懒加载把最初的plist文件加载后,根据plist文件文件中的目标控制器进行跳转,根据加载的plist文件中的plist_name加载将要跳转进去的控制器界面的控件等等.

  • 以上根据target_vc创建对应的目标控制器

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    NSDictionary * group = self.groups[indexPath.section];
    NSDictionary * item = [group[@"items"] objectAtIndex:indexPath.row];
    NSString * targetClassName = item[@"target_vc"];
    if (targetClassName) {
        //字符串转类
        Class TargetClass = NSClassFromString(targetClassName);
        //所有控制器都继承自UIViewControler用他来接收,并创建对应目标控制器类型
        UIViewController * destVc = [[TargetClass alloc] init];
        if ([destVc isKindOfClass:[PBBSettingViewController class]]) {
            PBBSettingViewController * settingVc = (PBBSettingViewController *)destVc;
            
            //如果点击的cell可以跳转新的"设置控制器"则,将group懒加载的self.plistname修改为要跳转的plist文件名,在这里则根据key--plist_name键取相应的plist文件名,进行跳转准备,准备内部控件
            settingVc.plistName = item[@"plist_name"];
            
        }
        destVc.navigationItem.title = item[@"title"];
        [self.navigationController pushViewController:destVc animated:YES];
    }
    
}


  • 如果目标控制器是类似设置的控制器,则强转为设置类型的控制器,由于继承其所有方法与属性,则可以加载对应的plist文件对齐内部控件进行赋值等操作.

  • 看图分析plist文件层级结构

  • 首先整个plist是个数组,数组内部对应的成员都是字典,字典内部对应的tableView的每组的成员 有 header 和 footer 以及内部的cell,所以字典内部存放的是以字典存储的header和footer以及以数组存放的cell们,每个cell又是一个字典用来取对应的图片资源 或者 创建对应的目标控制器以及目标plist文件.

  • 本文几乎全部是tableview,则通过懒加载来获取plist文件数据.通过数据源方法来对获取的数据进行解析--对控件进行创建以及赋值.

以下代码是控制代码,用来获取plist文件,把通过plist文件获取的资源赋给对应的tableView的控件



#import "PBBSettingViewController.h"
#import "PBBSettingCell.h"

@interface PBBSettingViewController ()

@property(nonatomic,strong)NSArray * groups;

@end

@implementation PBBSettingViewController

-(NSArray *)groups{

    if (_groups == nil) {
        NSString * path = [[NSBundle mainBundle] pathForResource:self.plistName ofType:nil];
        _groups = [NSArray arrayWithContentsOfFile:path];
    }
    return _groups;
}

#pragma mark - 数据源
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    //多少个组
    return self.groups.count;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    //先获取组
    NSDictionary * dict = self.groups[section];
    //获取组中对应items的数量 -- 每组cell的数量
    NSArray * arr = dict[@"items"];
    return arr.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    NSDictionary * group = self.groups[indexPath.section];
    NSDictionary * item = [group[@"items"] objectAtIndex:indexPath.row];
    
    //由于跳转的控制器的tableView的cell的sytle不同则在cell内部封装判断cell的style的方法.并且需要在编写plist文件中写上cell的style用来用key键取值去判断相应cell的style.item是获取一组cell中单个的cell以及属性.
    
    PBBSettingCell * cell = [PBBSettingCell settingCellWith:tableView item:item];
    
    //调用了item的set方法,在PBBSettingCell.m文件中实现了item的set方法,在set方法中进行了对cell内部子控件(左边icon头像的判断,中间title,以及details,右边accessory的判断以及赋值)的赋值.
    cell.item = item;
    return cell;
    
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    NSDictionary * group = self.groups[indexPath.section];
    NSDictionary * item = [group[@"items"] objectAtIndex:indexPath.row];
    NSString * targetClassName = item[@"target_vc"];
    if (targetClassName) {
        //字符串转类
        Class TargetClass = NSClassFromString(targetClassName);
        //所有控制器都继承自UIViewControler用他来接收,并创建对应目标控制器类型
        UIViewController * destVc = [[TargetClass alloc] init];
        if ([destVc isKindOfClass:[PBBSettingViewController class]]) {
            PBBSettingViewController * settingVc = (PBBSettingViewController *)destVc;
            
            //如果点击的cell可以跳转新的"设置控制器"则,将group懒加载的self.plistname修改为要跳转的plist文件名,在这里则根据key--plist_name键取相应的plist文件名,进行跳转准备,准备内部控件
            settingVc.plistName = item[@"plist_name"];
            
        }
        destVc.navigationItem.title = item[@"title"];
        [self.navigationController pushViewController:destVc animated:YES];
    }
    
}

-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{

    NSDictionary * group = self.groups[section];
    return group[@"footer"];
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

    NSDictionary * group = self.groups[section];
    return group[@"header"];
}


//设置tableView为分组的样式,重写构造init方法
-(instancetype)init{

    return [super initWithStyle:UITableViewStyleGrouped];
}

-(instancetype)initWithStyle:(UITableViewStyle)style{

    return [super initWithStyle:UITableViewStyleGrouped];
}

//设置返回按钮 格式 不同状态下的显示图片
-(void)viewDidLoad{

    [super viewDidLoad];
    
    UIBarButtonItem * backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"NavBack"] style:UIBarButtonItemStylePlain target:self action:@selector(didClickBackButton)];
    
    self.navigationItem.rightBarButtonItem.title = @"常见问题";
    self.navigationItem.title = @"设置哦!";
    self.navigationItem.leftBarButtonItem = backItem;
    
}
//如果自定义了返回按钮,则返回按钮进入上一个控制器需要手动返回.
-(void)didClickBackButton{

    [self.navigationController popViewControllerAnimated:YES];
    
}

@end



以下是在cell.m文件中对传递进来的数据进行解析---创建控件---对控件进行赋值(控件头像,title,以及accessory类型等等的判断)


#import "PBBSettingCell.h"

@implementation PBBSettingCell

//通过plist文件中的cell_style来创建对应的cell的style
+(UITableViewCellStyle)cellStyleWithText:(NSString *)cellStyle{

    if ([cellStyle isEqualToString:@"UITableViewCellStyleSubtitle"]) {
        return UITableViewCellStyleSubtitle;
    } else if ([cellStyle isEqualToString:@"UITableViewCellStyleValue2"]){
    
        return UITableViewCellStyleValue2;
    } else if([cellStyle isEqualToString:@"UITableViewCellStyleValue1"]){
    
        return UITableViewCellStyleValue1;
    } else {
        return UITableViewCellStyleDefault;
    }
}

//这个有卵用??-------暂时没有用...
+(instancetype)settingCellWith:(UITableView *)tableView{

    static NSString * ID = @"settigs_cell";
    PBBSettingCell * cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[PBBSettingCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    
    //颜色可以随便设置
    cell.detailTextLabel.textColor = [UIColor colorWithRed:173.0/255.0 green:166.0/255.0 blue:144.0/255.0 alpha:1.0];
    return cell;
}
+(instancetype)settingCellWith:(UITableView *)tableView item:(NSDictionary *)item{

    static NSString * ID = @"settigs_cell";
    PBBSettingCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        
        cell = [[PBBSettingCell alloc] initWithStyle:[self cellStyleWithText:item[@"cell_style"]] reuseIdentifier:ID];
    }
    cell.detailTextLabel.textColor = [UIColor colorWithRed:173.0/255.0 green:166.0/255.0 blue:144.0/255.0 alpha:1.0];
    return cell;
}

-(void)setItem:(NSDictionary *)item{

    _item = item;
    //判断是否有头像
    if (item[@"icon"]) {
        self.imageView.image = [UIImage imageNamed:item[@"icon"]];
    }
    
    self.textLabel.text = item[@"title"];
    self.detailTextLabel.text = item[@"details"];
    //设置判断accessory
    if (item[@"accessory"] && [item[@"accessory"] length]>0) {
        //字符串转换为类
        Class AccessoryClass = NSClassFromString(item[@"accessory"]);
        id accessory_obj = [[AccessoryClass alloc] init];
        //判断是否有图片框 没有图片框就是UISwitch类型或者是什么都没有...
        if ([accessory_obj isKindOfClass:[UIImageView class]]) {
            
            UIImageView * imageView = (UIImageView *)accessory_obj;
            imageView.image =  [UIImage imageNamed:item[@"accessory_img"]];
            [imageView sizeToFit];
        }
        self.accessoryView = accessory_obj;
    }
    
}

- (void)awakeFromNib {
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end



总结:类似这种控制器的跳转,跳转后还需要进行跳转的"设置"类型的跳转,需要自己写plist文件的,而且跳转后的控制器的都基本是同一种控制器例如tableViewController,可以在plist文件中写入所有的tableView的属性,因为可能跳转进入不同的控制器界面对应的控件有所不同,有的就写上,创建什么类型的cell进行判断即可.