点步

导航

tableView 注意点


  1 1. 使用UITableView的"静态单元格"  2 (注意: 使用静态单元格, 必须使用UITableViewController控制器)
  3     * 什么是静态单元格? 什么是动态单元格?
  4     1> 静态单元格不会随着数据的改变而改变, 当在storyboard中设计的时候是什么样子, 最后运行效果就是什么样子, 并且不会随着数据的变化而变化。如果要想改变静态单元格内容, 必须重新修改代码。
  5     2> 动态单元格在设计的时候只是将单元格的"框架(壳子)"设计好了, 设置好了位置、大小、背景色等基本信息, 里面的具体数据内容, 需要在程序运行时, 通过动态获取数据再显示到单元格中。优点: 只要修改了数据模型, 那么对应的单元格内容就发生变化了。
  6 
  7 
  8     * 什么情况下使用静态单元格?什么情况下使用动态单元格?
  9     1> 静态单元格使用场景: 有些界面的内容是固定的, 并且基本上不会发生任何改变, 此时使用"静态单元格"来创建该界面, 非常方便。
 10     2> 动态单元格使用场景: 有些界面的内容会随着数据的变化而不断变化, 这些界面都需要使用"动态单元格", 随时根据相应的数据而变化。
 11 
 12 
 13     ** 演示:通过数据源方法来实现"QQ动态"界面效果。(使用UITableViewController)
 14     1> 分析如果要把动态内容的数据使用plist文件来保存, 那么如何设计该plist文件。
 15 
 16 
 17     ** 演示:通过使用"静态单元格"的方式来实现"QQ动态"界面效果。
 18     /********************************************************************************************/
 19     (注意: 使用静态单元格, 必须使用UITableViewController控制器)
 20     /********************************************************************************************/
 21 
 22 
 23     * 静态单元格使用建议:
 24     1> 先保留1个Section, 1个Cell。
 25     2> 设置好这个Cell以后, 在设置section的个数以及每个section中行的个数。
 26 
 27     * 静态单元格设置大致步骤:
 28     1> 选中TableView设置Content为static cell(静态单元格)
 29 
 30     2> 删除静态单元格, 只保留一个。
 31 
 32     3> 选中TableView设置style为grouped
 33 
 34     4> 选中单元格, 设置设置style为basic、设置Accessory为Disclosure Indicator。
 35 
 36     5> 双击"Title"设置文字.
 37 
 38     6> 选中单元格设置Image属性为: found_icons_qzone
 39     6.1> 选中 UITableView设置 style 为 Grouped
 40 
 41     7> 选中tableView设置Section为 3 42 
 43     8> 选中第二个Section设置Rows为 2
 44 
 45     9> 选中第三个Section设置Rows为 3
 46 
 47 
 48     ** 注意: 当设置了数据源对象, 并且实现了数据源方法的时候, 即便有静态单元格也优先调用数据源方法来生成数据。
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 2. 动态加载"QQ好友列表" 57 
 58     ** 步骤:
 59     1> 创建Group模型对象、Friend模型对象
 60     ** 注意, 加载数据时, 要把friends属性由"字典"集合转为"模型"集合。
 61 
 62     2> 懒加载数据
 63 
 64 
 65     3> 实现数据源方法, 显示好友列表数据(虽然可以使用系统默认的Cell, 但还是建议封装一个自定义Cell。)。
 66     ** 自定义一个Cell类继承自UITableViewCell类, 实现封装创建可重用单元格的代码以及一个模型属性。
 67     ** 这个自定义Cell中只使用到了Friend模型数据, 没有用到Group模型的相关内容, 所以只传递一个Friend模型到Cell中即可
 68 
 69 
 70     4> 设置分组的Header内容。
 71     * 演示: 先演示通过Storyboard的方式操作按钮的现实效果(左对齐、内边距等。)
 72     ** 注意: 虽然这里的每一组的子元素样子是一样的, 但是不能使用 xib 来实现, 因为 在 xib 中无法拖拽一个UITableViewHeaderFooterView控件, 所以依然需要完全自定义一个UITableViewHeaderFooterView类
 73     /**
 74         由于此时的Header View不再是普通文字了, 所以使用如下代理方法设置Header View
 75      
 76         (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
 77      */
 78 
 79 
 80     ** 注意, 设置按钮内容水平左对齐
 81         // nameBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
 82 
 83     ** 注意, 设置按钮内容的内边距
 84         // btnGroupName.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
 85 
 86     ** 注意, 设置标题文字与按钮中的ImageView之间的间距
 87         // btnGroupName.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
 88 
 89     ** 注意, 设置按钮文字大小(加粗,18号)
 90         // btnGroupName.titleLabel.font = [UIFont boldSystemFontOfSize:18];
 91 
 92     ** 注意, 设置label文字右对齐
 93     // lblCount.textAlignment = NSTextAlignmentRight;
 94 
 95     ** 注意, 设置label文字为灰色
 96     // lblCount.textColor = [UIColor grayColor];
 97 
 98     ** 注意, 在viewDidLoad中统一设置Section的行高:
 99     // self.tableView.sectionHeaderHeight = 44;
100 
101 
102     5> 自定义UITableViewHeaderFooterViewe类。
103     * 虽然这里的每一组的子元素样子是一样的, 但是不能使用 xib 来实现, 因为 在 xib 中无法拖拽一个UITableViewHeaderFooterView控件, 所以依然需要完全自定义一个UITableViewHeaderFooterView类
104     * 在 viewDidLoad 方法中统一设置所有组的高度self.tableView.sectionHeaderHeight = 44;
105 
106     * 通过设置每一个UITableViewHeaderFooterViewe的 contentView 的背景色来观察每一个 header view。
107     *设置控件的frame,在layoutSubviews这个方法中设置(必须重写父类方法)
108     * setGroupModel:设置子控件的数据值
109 
110 6> 点击展开、闭合分组
111     * 思路:在TableView的数据源方法tableView:numberOfRowsInSection:中返回0, 则表示关闭。
112         1> 为Group Header中的按钮注册单击事件
113         2> 在Group模型中, 增加一个BOOL类型属性isVisible, 表示当前分组是否可见。(默认为NO)
114         3> 在用户单击事件中修改该属性的值为原来值得反面。isVisible = !isVisible
115         4> 同时要想执行tableView:numberOfRowsInSection:方法, 必须重新reloadData。
116     ** 注意: 如果全都设置了,但是点击就是没有效果,那么检查一下是不是忘记在set方法中为模型对象赋值了, 所以isVisible永远都是NO。
117         5> 局部刷新某组: 通过调用 tableView 的 reloadSections:方法来实现, 在 headerView 的 Tag中记录当前组的索引。
118 
119     /** 实现点击按钮, 打开\闭合组
120         1. 为按钮注册单击事件
121      
122         2. 重写数据源方法中返回每个section的行个数的方法.
123      
124         3. 重新调用tableView的reloadData方法,(就会重新执行数据源方法, 就可以重新获取每个section的组的个数)
125             ** 当这个section的组返回的个数是0的时候, 那么这个组看起来就"闭合"了.
126      
127         4. 在返回每个section的行的数据源方法中, 需要通过一个标记来判断当前应该返回0行还是实际的行数.
128      
129         5. 在headerView中无法直接刷新tableView, 需要通过代理来实现.
130      */

 

 

1
7> 旋转分组名称旁边的"三角图片" 2 * 思路: 设置按钮中的ImageView旋转90度。通过transform 3 1> 在按钮的单击事件中执行旋转: 4 // self.btnGroupName.imageView.transform = CGAffineTransformMakeRotation(M_PI_2); 5 6 2> 旋转无效?原因: 当tableView重新reloadData的时候, Header View被替换了, 变成了新的Header View。也就是说已经旋转了, 但是当reloadData的时候, 又产生了一个新的Header View, 所以看不到效果了。【解决: 在reloadData以后, 在新的Header View 加进来以后, 再执行旋转, 使用UIView的】 7 **注意: 不能重用Header View的原因是调用了reloadData方法了。”重用Cell”、”重用headerView”指的是在滚动的时候重用。 8 /** 参考代码: 9 - (void)didMoveToSuperview 10 { 11 // 旋转 12 if (self.group.isVisible) { 13 self.btnGroupName.imageView.transform = CGAffineTransformMakeRotation(M_PI_2); 14 } else { 15 self.btnGroupName.imageView.transform = CGAffineTransformMakeRotation(0); 16 } 17 } 18 19 */ 20 21 3> 旋转变形?原因: 按钮中的ImageView本身并没有发生大小改变, 当旋转的时候ImageView中的内容(图片)发生了旋转, 同时为了适应ImageView, 被拉伸了, 所以变形。【解决: 设置按钮中的ImageView的内容模式为"居中显示", 不拉伸】 22 // btnGroupName.imageView.contentMode = UIViewContentModeCenter; 23 24 4> 图片旋转后被裁减了? 原因: 当图片旋转后, 如果不自动缩放、拉伸, 会有部分内容超出ImageView, 那么此时imageView会自动不显示这部分内容。【解决: 设置ImageView不自动裁减】 25 // btnGroupName.imageView.clipsToBounds = NO;

 





1
9> 解决 header view 重用的时候, 按钮的三角图片显示不正常问题 2 ** 在 setGroup 方法中重置单元格的图片旋转 3 // 解决单元格重用的时候"小三角"图片旋转不正常的问题 4 if (self.group.isVisible) { 5 self.btnGroupTitle.imageView.transform = CGAffineTransformMakeRotation(M_PI_2); 6 } else { 7 self.btnGroupTitle.imageView.transform = CGAffineTransformMakeRotation(0); 8 }

 

 


"App管理"案例。 ** 知识点: 1> 使用UITableView中的Cell来代替xib。(使用storyboard 中的 UITableView的 Cell 模板, 代替 xib) 2> 循环利用Cell时的一个问题。(注意点: 在重用Cell之前,需要重新设置Cell的数据和状态。) 3> 复习代理。(点击自定义Cell中的按钮, 在控制器中显示一个对话框) ** 步骤: 1> 使用UITableViewController。 2> 创建一个自定义个Tabe View 控制器类, 与控制器关联。 3> 创建model 4> 懒加载apps_full.plist数据。 5> 实现数据源方法 6> 系统默认Cell不足以显示app单元格, 每个行的Cell样子一样, 所以想到了用xib。但是这里使用另外一个东西来代替xib。就是UITableView中的cell. 7> 创建一个自定义的cell类与storyboard中的Cell相关联。 8> 修改TableView的行高为60. 9> 为storyboard中的Cell指定一个identifier(重用ID) 10> 在数据源方法中, 调用HMAppCell *cell = [tableView dequeueReusableCellWithIdentifier:@"appcell"];来创建Cell。该方法首先从缓存池中查找对应的可重用Cell,如果没有则去storyboard中查找与identifier相同的Cell。 11> 演示创建不同的Cell模板(需要为每个CEll指定不同的identifier),加载的时候根据不同的identifier来加载不同的Cell。 /*** 参考代码: 加载storyboard中的cell的方式: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 这个方法会先尝试从队列中查找,找不到则取storyboard中找identifier的值为@“appcell”的单元格。 HMAppCell *cell = [tableView dequeueReusableCellWithIdentifier:@“appcell”]; cell.app = self.apps[indexPath.row]; cell.delegate = self; return cell; } */

 

 

12> 为自定义Cell类传递数据。

    13> 点击下载:

        1. 禁用下载按钮

        2. 显示"已下载"。通过代码或者设置Disabled状态下显示文字为"已下载"

        3. 弹出提示对话框。

    14> 解决循环利用Cell的时候"下载"按钮的状态问题。

        ** 注意: 当循环利用Cell的时候, 每次使用Cell前不仅要修改Cell的数据, 还要修改Cell状态。

        ** 在模型中增加一个BOOL类型属性donwloaded, 用来标记是否已经下载, 如果是, 则在设置数据的时候禁用该按钮,否则启用。

 

 

注意: 在重写layoutSubviews方法的时候, 不要忘记调用父类的layoutSubviews方法, 否则按钮点击无效果、不会切换normal与highlighted效果等。

// [super layoutSubviews];

* 注意: layoutSubviews方法在当某个控件的frame发生改变时, 会自动调用。在这个方法中可以重新布局子控件。

 

* 提示: - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 设置每个Section的高度。

 

* 注意: 大多数UIView的子控件在执行init方法的时候或者刚执行完毕init方法的时候frame的值都是0, 需要我们手动来设置, 或者系统在某个时候自动设置。

 

/************************************************************************/

补充: 解释一个问题:为什么每次懒加载数据的时候都要创建一个新的NSMutableArray数组?原因是一开始属性是nil。

 

 

=====

* 某个控件显示不出来可能的原因:

1. frame属性,是否为0,位置不对

2. hidden = YES

3. 是否添加到了父控件中

4. Alpha < 0.01

5. 被其他控件挡住了。

6. 检查父控件的上面这5种情况。

posted on 2015-11-06 00:01  点步  阅读(511)  评论(0编辑  收藏  举报