列举简单实例,学习封装

  • 简单的tableView的实现。

    • 数据模型
      • 组模型
        • 行模型数组(对应的是每一行cell的值)
        • 头部标题
        • 底部标题
      • 行模型 (对应cell)(与cell的内部的属性相对应)
        • 文字属性
        • 图片属性
    • cell控件
    • 数据源方法
      • 组数
      • 行数
      • 每行的cell值
      • 每组的头标题
      • 每组的底标题
    • 代理方法
      • 点击了cell实现某种方法
  • tableView是一个最能体现MVC思想的控制器之一,控制器提供数据,数据转换模型,模型修改控件属性,控制器刷新控件,让控件显示模型更新数据。(话语实现就是这样,但真的做的时候,需要一步步思考。)

    • [编程思路,由大到小]
    • [实现思路,由小到大]
    • [封装思路,方便使用,管理,由外及内]。
  • 对于tableView的实现。

    • 添加数据(用什么添加,那什么接收)
    • 实现数据源方法
  • 添加数据(用模型添加,拿数组接收)

    • 接收数组(添加的时候才使用,所以想到懒加载)

      // 类扩展中添加属性(因为无需与外界就行传递,交互,所以写在类扩展中最好)
      @property (nonatomic,strong) NSMutableArray *groups
      
      // 懒加载
      - (NSMutableArray *)groups
      {
          if(!_groups)
          {
              _groups = [NSMutableArray Array];
          }
          return _groups;
      }
      
    • 添加组模型数据

      • 组模型数据要加到数组中
        [self.groups addObject: group];
      • 组模型是有行模型数组和头尾标题组成的,所以就有了组模型的模型搭建
//模型的所有属性,几乎都是用来让外界使用的,所以属性都写在外边即可。并提供类方法,方便外界创建模型(所谓模型,就是把数据整合化).h文件中的

// 头部标题
@property (nonatomic,copy) NSString *headerTitle;

// 尾部标题
@property (nonatomic,copy) NSString *footerTitle;

// 行模型数组
@property (nonatomic,strong) NSArray *items;

// 构造方法(以类名开头)(简单的不许要传参数, 复杂的传参数,但是无非就是把传入的参数,给自己的属性进行赋值)
+ (instancetype)group;

// .m中的实现方法
+ (instancetype)group
{
    LXLGroupItem *group = [[self alloc]init];
    return group;
}
/* 这里解释两个事情
    1.为什么用instancetype,而不用id。非常实用的一点是instancetype代指的是:实例对象,id代指的是:任何对象,有时候简单数据变量都可以。 这就局限了id是不能实现点语法,而instancetype是可以实现的。
    2. 为什么用self,而不用当前类(LXLGroupItem),这是为了继承,以及程序扩展性才这么写的,以后也必须这么写。如果自己有子类,那么子类就会继承自己的方法,但是如果写成了LXLGroupItem,就一直创建的是父类对象,而不是子类对象。(有些需求是子类独有的,所以必须创建子类对象) (这是继承中的内容)。
*/
  • 怎么方便使用,
    • LXLGroupItem *group = [LXLGroup group];
    • group.headerTitle = @"..."
    • group.footerTitle = @"..."
    • group.items = @[ , , ,...];
  • 行模型创建 (模仿组模型进行创建)(模型都继承自NSObject,因为其内部就是一群数据。个人觉得就是数据的归类)
    • 具有的属性 (根据cell而定)
    • 提供构造方法
  • 实现数据源方法

    • 有多少组 self.groups.count
    • 每一组对应的行数
      • 取出组模型 LXLGroupItem *group = self.groups[section];
      • 对应的行数 group.item.count
    • 每行显示的数据
      • 取出组模型LXLGroupItem *group = self.groups[indexPath.section];
      • 取出行模型LXLItem *item = group.item[indexPath.row];
      • 模型属性进行赋值操作。cell.... = item...
      • .....
  • 思考

    • 一般我们实现最简单的数据源方法的确是这样,但是往往我们常常会有其他的考虑,比如缓存池的情况,比如cell的Accessory的标志,以及cell类型等等的考虑。
    • 我们不应该让外界知道我们有如此的设计,让程序分工明确,所以这些独属于cell的设置,由cell内部进行考虑。
  • 外界如何使用:

    • 创建cell,
    • 给cell赋值
    • 返回cell
  • 创建cell ,

    • 对于tableView来说,cell先从缓存池中读取,在进行判断,如果没有的话则进行创建,创建过程中需要设置其类型
    • 传入参数应该有缓存池的tableView,以及所要的类型
  • 给cell赋值

    • cell赋值最简单的方式则为 ,cell.item = item;直接接收模型属性,在其内部一一赋值。
    • 对于accessoryView的选择应该也由模型决定
      • 两种方案

        • 模型属性中添加两个属性,用来决定accessoryView。
        • 给模型加子类,由类名来区别accessoryView。
      • 选择第二种方案,应为更符合封装思想,不同的类管理不同的模型。(创建模型时,用不同类进行创建)

  • 代码实现

// 构造方法,创建cell
+ (instancetype)cellWithTableView:(UITableView *)tableView withStyle:(UITableViewCellStyle )style
{

    static NSString *ID = @"setting";
    LXLSettingCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[self alloc]initWithStyle:style reuseIdentifier:ID];
    }
    return cell;

}

// 外界接收到item,拿来一一赋值
- (void)setItem:(LXLSettingItem *)item
{
    _item = item;
    [self setUp];
    [self setUpAccessoryView];
}

- (void)setUp
{
    self.imageView.image = _item.image;
    self.textLabel.text = _item.title;
    self.detailTextLabel.text = _item.subTitle;


}
// 根据接收过来的item的类,进行选择。
- (void)setUpAccessoryView
{

    // 先if 再 else if 再 else 按顺序来,有个良好的习惯
    if ([_item isKindOfClass:[LXLSettingItemArrow class]]) {
        UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage  imageNamed:@"arrow_right"]];
       self.accessoryView = imageView;

    }else if ([_item isKindOfClass:[LXLSettingItemSwitch class]]) {
        UISwitch *switchView = [[UISwitch alloc]init];
       self.accessoryView = switchView;
    }else{

        self.accessoryView = nil;
    }



}
  • 关于block的强大使用。

    • 封装代码块,可以传入参数。
    • 把事件包装起来,并传入参数。
  • 思考

    • 对于tableView的实现,那么它的cell 应该有点击跳转到某个控制器的功能。(每个cell对应不同的控制器,cell决定控制器,而模型决定cell,所以模型决定控制器跳转。)对于要跳转的控制器应该由它cell的模型属性进行决定。
    • 两种方案进行选择:
      • 模型加入属性:
        • 直接加入控制器

        • @property (nonatomic,strong) UIViewController *vc [控制器必须强引用]

        • 加一个属性显示控制器的类名

        • `@property(nonatomic,assign) Class vc;

        • 另一种方式用block封装代码块,来执行事件,

    • 注意block定义式
    • void(^方法名)(参数类型+参数名)
      @property (nonatomic,strong) void(^block)();
    • block的定义,只是定义了里面的事件,但并没有去实现
      定义: void(^block)(int a , int b) = ^(int a, int b){
      NSLog(@“%d”,a+b);
      }
    • 只有调用了block( ),才能进行block的实现
      实现: block(10,15); 他就会执行这个block, 打印25.
  • 所以对于一些事件可以封装到block中

    • 此处先进行跳转的封装说明吧
      // block 写法为 ^ + ( 参数 类名+参数名) {要完成的事,一般传入事件} ,但要注意循环引用 有self,或者成员属性,一定要将self 变为弱指针 __weak typeof(self) weakSelf = self; item.block = ^(NSIndexPath *path){ LXLRedeemController *vc = [[LXLRedeemController alloc]init];
      vc.navigationItem.title = @"提醒和推送";
      [weakSelf.navigationController pushViewController:vc animated:YES];
      };
    • 当点击此cell的时候,进行判断,看是否有block的存在
      如果有则执行block
    • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; LXLGroupItem *group = self.groups[indexPath.section];
      LXLSettingItem *item = group.items[indexPath.row];

    if (item.block) {
    // 传入参数确定是哪一行的cell被点击了
    item.block(indexPath);
    }
    }

  • 对于添加类名属性来进行跳转的代码实现

  • item. vc = [UITableViewController Class];

  • 点击cell时 同样进行判断 此属性是否有值
    如果有,则创建对应的控制器,进行跳转。

需要注意的是:此类跳转只针对与 cell的accessoryView 是箭头的操作,如果是switch的话,则跳出蒙版。

  • 所以vc属性只能针对与箭头模型。 如果点击了cell,则取出模型,判断其类型,然后在执行跳转还是弹出蒙版。
  • 对于最后的结论,用block最好
    - 无论 弹出蒙版,还是跳转页面,总之都是进行了一定的事件。将其事件交给block,当点击cell 执行事件即可, 无需判断类型。
    - 总之,对于点击cell处理的事件以后都交给block进行管理最好了

  • 对于cell点击弹出键盘事件

  • 首先应该应该想到

    • 点击什么样的cell弹出键盘,
    • 键盘怎么才能弹出。
    • 键盘是由哪行cell引出的
    • 什么时候退出键盘
    item.block = ^(NSIndexPath *path){               // 只要确定选中的行,就能够让键盘弹出后,不挡住选中的行        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:path];        UITextField *textField = [[UITextField alloc]init];        [textField becomeFirstResponder];        [cell addSubview:textField];       
    };

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    LXLGroupItem *group = self.groups[indexPath.section];
    LXLSettingItem *item = group.items[indexPath.row];
    if (item.block) {
        item.block(indexPath);
     }
}
  • 退出键盘
    滚动时退出键盘
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{    [self.view endEditing:YES];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 概述在iOS开发中UITableView可以说是使用最广泛的控件,我们平时使用的软件中到处都可以看到它的影子,类似...
    liudhkk阅读 8,908评论 3 38
  • 2017.02.22 可以练习,每当这个时候,脑袋就犯困,我这脑袋真是神奇呀,一说让你做事情,你就犯困,你可不要太...
    Carden阅读 1,306评论 0 1
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,703评论 1 92
  • 【21天一起写10月23日第15天】 #硕妈田生万物创业日记#第15天#我的“暖男”老公# 今天有这样一条新闻,在...
    硕妈亲子盟阅读 193评论 0 0
  • 上学时鼓励学生好好学习最常听到的话就是“知识改变命运”,尽管如此也不见得每个人都心服口服,应试教育下的学生,目的感...
    Zora_七公子阅读 223评论 0 1