tableView的属性
TableView的样式
tablview 初始化,xib的定义
typedef NS_ENUM(NSInteger, UITableViewStyle) {
UITableViewStylePlain, // regular table view 标准的表视图风格
UITableViewStyleGrouped // preferences style table view 有选择样式的分组的表视图风格
};
![](
!屏幕快照 2017-03-31 上午10.21.01.png](https://img.haomeiwen.com/i3248269/8b2fa1b29504488f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
)
scrollPosition参数决定定位的相对位置
self.tableView scrollToRowAtIndexPath:<#(nonnull NSIndexPath *)#> atScrollPosition:<#(UITableViewScrollPosition)#> animated:<#(BOOL)#>
typedef NS_ENUM(NSInteger, UITableViewScrollPosition) {
UITableViewScrollPositionNone, //同UITableViewScrollPositionTop
UITableViewScrollPositionTop, //定位完成后,将定位的行显示在tableView的顶部
UITableViewScrollPositionMiddle, //定位完成后,将定位的行显示在tableView的中间
UITableViewScrollPositionBottom //定位完成后,将定位的行显示在tableView最下面
}; // scroll so row of interest is completely visible at top/center/bottom of view
行变化(插入、删除、移动的动画类型)
插入时的动画效果:UITableViewRowAnimationFade
self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
typedef NS_ENUM(NSInteger, UITableViewRowAnimation) {
UITableViewRowAnimationFade, //淡入淡出
UITableViewRowAnimationRight, //从右滑入 // slide in from right (or out to right)
UITableViewRowAnimationLeft , //从左滑入
UITableViewRowAnimationTop, //从上滑入
UITableViewRowAnimationBottom, //从下滑入
UITableViewRowAnimationNone, //没有动画 // available in iOS 3.0
UITableViewRowAnimationMiddle, // available in iOS 3.2. attempts to keep cell centered in the space it will/did occupy
UITableViewRowAnimationAutomatic = 100 // 自动选择合适的动画// available in iOS 5.0. chooses an appropriate animation style for you
};
tableViewCell右滑时自定义添加多个按钮
typedef NS_ENUM(NSInteger, UITableViewRowActionStyle) {
UITableViewRowActionStyleDefault = 0,
UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault,
UITableViewRowActionStyleNormal
![效果图代码如下](
!屏幕快照 2017-03-31 上午10.58.46.png](https://img.haomeiwen.com/i3248269/0e305b84cbdfe7df.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
)
//设置可以编辑
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
//设置编辑操作:删除
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
//自定义按钮
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *layTopRowAction1 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(@"点击了删除");
[tableView setEditing:NO animated:YES];
}];
layTopRowAction1.backgroundColor = [UIColor redColor];
UITableViewRowAction *layTopRowAction2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"置顶" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(@"点击了置顶");
[tableView setEditing:NO animated:YES];
}];
layTopRowAction2.backgroundColor = [UIColor greenColor];
UITableViewRowAction *layTopRowAction3 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"更多" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(@"点击了更多");
[tableView setEditing:NO animated:YES];
}];
layTopRowAction3.backgroundColor = [UIColor blueColor];
NSArray *arr = @[layTopRowAction1,layTopRowAction2,layTopRowAction3];
return arr;
}
自定义添加多个按钮的方法
+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(nullable NSString *)title handler:(void (^)(UITableViewRowAction *action, NSIndexPath *indexPath))handler; //加block
@property (nonatomic, readonly) UITableViewRowActionStyle style;
@property (nonatomic, copy, nullable) NSString *title;
@property (nonatomic, copy, nullable) UIColor *backgroundColor; default background color is dependent on style 默认背景颜色取决于系统
@property (nonatomic, copy, nullable) UIVisualEffect* backgroundEffect;
为视图实现特殊效果(模糊)
UITableViewDelegate
通常都要为UITableView设置代理对象(delegate),以便在UITableView触发一下事件时做出相应的处理,比如选中了某一行。凡是遵守了UITableViewDelegate协议的OC对象,都可以是UITableView的代理对象。
![](
!屏幕快照 2017-03-31 下午1.15.53.png](https://img.haomeiwen.com/i3248269/8febbb29740a194c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
)
@optional UITableViewDelegate<NSObject, UIScrollViewDelegate>
自定义
cellForRowAtIndexPath与willDisplayCell的区别
cellForRowAtIndexPath是data source协议中一个必须实现的方法,willDisplayCell是delegate协议中一个可选的方法。
cellForRowAtIndexPath中创建一个可重用的cell实例,我们应该尽量快的返回创建的cell,对于数据的绑定之类的操作应该放到willDisplayCell中去处理;
willDisplayCell在cell 在tableview展示之前就会调用,此时cell实例已经生成,所以不能更改cell的结构,只能是改动cell上的UI的一些属性(例如label的内容等)
// Display customization
# 将要展示cell/header/footer
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
//将要显示指定索引处的单元格
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
//将要显示指定区的表头视图
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
//将要显示指定区的表尾视图
# 完成展示cell/header/footer
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath NS_AVAILABLE_IOS(6_0);
//完成显示指定索引处的单元格
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
//完成显示指定区的表头视图
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
//完成显示指定区的表视图
可变高度支持
// Variable height support 可变高度支持
#每个cell、section-header、section-footer高度的返回(这里高度通过协议返回,是为了table能准确的定位出来要显示的Cell-index,从而满足UITableView的重用机制
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
//单元格行高
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
//指定区的表头高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
//指定区的表尾/页脚高度
设置行高(估计值)
// Use the estimatedHeight methods to quickly calcuate guessed values which will allow for fast load times of the table.
// If these methods are implemented, the above -tableView:heightForXXX calls will be deferred until views are ready to be displayed, so more expensive logic can be placed there.
# 设置行高,头视图高度和尾视图高度的估计值(对于高度可变的情况下,提高效率)
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(7_0);
//指定索引处的估算行高
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section NS_AVAILABLE_IOS(7_0);
//指定区估算的表头/页眉高度
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section NS_AVAILABLE_IOS(7_0);
//指定区估算的表尾/页脚高度
/*
self.tableView.rowHeight=UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight=44.0;
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
在 cellforrow 里调用 [cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
要结合起来 我之前 用Storybord做cell自使用 就使用这个方法
*/
section组头部以及尾部
// Section header & footer information. Views are preferred over title should you decide to provide both
#第section组头部以及尾部显示什么控件
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
// ——为指定区的页眉定制视图 custom view for header. will be adjusted to default or specified header height
- (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
//——为指定区的页脚定制视图 custom view for footer. will be adjusted to default or specified footer height
辅助
// Accessories (disclosures).
# 当cell的accessaryType为UITableViewCellAccessoryFetailDisclosureButton时,点击accessaryView将会调用delegate的tableView:accessoryButtonTappedForRowWithIndexPath方法。否则只只是didSelectRowAtIndexPath; (accessaryView 辅助视图)
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath NS_DEPRECATED_IOS(2_0, 3_0);
//指定索引处的表格行的附件类型
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;
//指定索引处的表格行的附件按钮被轻击时
组(高亮)
// Selection
// -tableView:shouldHighlightRowAtIndexPath: is called when a touch comes down on a row.
// Returning NO to that message halts the selection process and does not cause the currently selected row to lose its selected look while the touch is down.
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
//当前选中的row是否高亮
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
//指定row高亮
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
//通知委托表视图的指定行不在高亮显示,一般是点击其他行的时候
cell选择和取消选择
#cell选择和取消选择
// Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;
//将要选择指定索引处的表格行
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0);
//将要取消选择指定索引处的表格行
已经选择汇总和已经取消选择选中后调用的函数
// Called after the user changes the selection.
已经选择汇总和已经取消选择选中后调用的函数
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
//已经选择指定索引处的表格行
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0);
//已经取消选择指定索引处的表格行
编辑
// Editing
// Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) {
UITableViewCellEditingStyleNone,
UITableViewCellEditingStyleDelete, //删除样式
UITableViewCellEditingStyleInsert //插入样式
};
//返回指定索引位置表格行的编辑风格/样式
- (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0);
//返回指定索引处表格行上删除确认按钮上的标题文字
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0);
//指定索引行的表格行的编辑操作,返回 UITableViewRowAction对象组成的数组 supercedes(推迟,取代,接下来) -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: if return value is non-nil
// 8.0后侧滑菜单的新接口,支持多个侧滑按钮。
行缩进
// Controls whether the background is indented while editing. If not implemented, the default is YES. This is unrelated to the indentation level below. This method only applies to grouped style table views.
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath;
//判断当编辑指定索引处的表格行时是否将要 indent(缩进,订货),默认所有的表格行编辑状态时都会缩进,只对grouped的TableView有效
或者cell.shouldIndentWhileEditing = NO;
开始与完成编辑
// The willBegin/didEnd methods are called whenever the 'editing' property is automatically changed by the table (allowing insert/delete/move). This is done by a swipe activating a single row
- (void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath;
//将要开始编辑指定索引处的表格行
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath;
//指定索引处的表格行编辑完成
移动
// Moving/reordering
// Allows customization of the target row for a particular row as it is being moved/reordered
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;
// 移动特定的某行(注意区别之前的tableView:moveRowAtIndexPath:toIndexPath方法。当手指按住reorde accessory view移动时,只要有row moved/reordered都会调用该方法,而前者方法只有当手指放开reorder accessory view时,结束move/order操作才会调用自己。返回值代表进行移动操作后回到的行,如果设置为当前行,则不论怎么移动都会回到当前行
NSInteger类型的值——缩进水平
// Indentation
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath;
//返回NSInteger类型的值——缩进水平 return 'depth' of row for hierarchies
弹出选择菜单时会调用此方法(BOOL) 选择菜单项完成之后调用此方法(void)
// Copy/Paste. All three methods must be implemented by the delegate.
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(5_0);
//长按出来的Copy/Paste操作 (复制粘贴)----->通知委托是否在指定行显示菜单,返回值为YES时,长按显示菜单
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender NS_AVAILABLE_IOS(5_0);
//弹出选择菜单时会调用此方法(复制、粘贴、全选、剪切)
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender NS_AVAILABLE_IOS(5_0);
//选择菜单项完成之后调用此方法
Focus 焦点
// Focus 焦点
- (BOOL)tableView:(UITableView *)tableView canFocusRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
- (BOOL)tableView:(UITableView *)tableView shouldUpdateFocusInContext:(UITableViewFocusUpdateContext *)context NS_AVAILABLE_IOS(9_0);
- (void)tableView:(UITableView *)tableView didUpdateFocusInContext:(UITableViewFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator NS_AVAILABLE_IOS(9_0);
- (nullable NSIndexPath *)indexPathForPreferredFocusedViewInTableView:(UITableView *)tableView NS_AVAILABLE_IOS(9_0);
UITableView : UIScrollView <NSCoding>
继承于UIscrollView ->有scrollView的属性
scrollView
tableView 初始化 基本属性
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style NS_DESIGNATED_INITIALIZER; // must specify style at creation. -initWithFrame: calls this with UITableViewStylePlain
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
@property (nonatomic, readonly) UITableViewStyle style;
//tableView 的样式
@property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;
@property (nonatomic) CGFloat rowHeight; // will return the default value if unset 行高
@property (nonatomic) CGFloat sectionHeaderHeight; // will return the default value if unset 组头的高度
@property (nonatomic) CGFloat sectionFooterHeight; // will return the default value if unset 组尾的高度
@property (nonatomic) CGFloat estimatedRowHeight NS_AVAILABLE_IOS(7_0); // default is 0, which means there is no estimate 估算行高,默认0
@property (nonatomic) CGFloat estimatedSectionHeaderHeight NS_AVAILABLE_IOS(7_0); // default is 0, which means there is no estimate 估算组头的高度
@property (nonatomic) CGFloat estimatedSectionFooterHeight NS_AVAILABLE_IOS(7_0); // default is 0, which means there is no estimate 估算组尾的高度
@property (nonatomic) UIEdgeInsets separatorInset NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; // allows customization of the frame of cell separators 允许更改分割线的frame
//UIEdgeInsets:CGFloat top, left, bottom, right; // specify amount to inset (positive) for each of the edges. values can be negative to 'outset'
@property (nonatomic, strong, nullable) UIView *backgroundView NS_AVAILABLE_IOS(3_2); // the background view will be automatically resized to track the size of the table view. this will be placed as a subview of the table view behind all cells and headers/footers. default may be non-nil for some devices. 背景视图(自动匹配tableView视图大小),设置互作为列表视图的子视图,切在所有cell和headers/footers的后面,默认为nil
Data 数据的刷新
- (void)reloadData; // reloads everything from scratch. redisplays visible rows. because we only keep info about visible rows, this is cheap. will adjust offset if table shrinks 刷新列表
- (void)reloadSectionIndexTitles NS_AVAILABLE_IOS(3_0); // reloads the index bar. 刷新你section这个方法常用语新加或者删除了索引类别二无需率先呢整个表视图的情况下
##
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0); // 刷新某些组
3
Info 信息
@property (nonatomic, readonly) NSInteger numberOfSections; // 列表的组数
- (NSInteger)numberOfRowsInSection:(NSInteger)section; // 某一组有多少行
- (CGRect)rectForSection:(NSInteger)section; // includes header, footer and all rows 某一组所占的矩形区域(包括header,footer和所有的行)
- (CGRect)rectForHeaderInSection:(NSInteger)section; // 某一组的header所占的矩形区域
- (CGRect)rectForFooterInSection:(NSInteger)section; // 某一组的footer所占的矩形区域
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath; // 某一分区的row所占的矩形区域
- (nullable NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point; // returns nil if point is outside of any row in the table 某一点在tableView上所占的分区,如果该点不在tableView的任何row上返回nil
- (nullable NSIndexPath *)indexPathForCell:(UITableViewCell *)cell; // returns nil if cell is not visible 某一行所在的分区,如果改行是不可见的返回nil
- (nullable NSArray<NSIndexPath *> *)indexPathsForRowsInRect:(CGRect)rect; // returns nil if rect not valid 某一矩形区域内所有行所在的所有分区,返回元素为NSIndexPath类型的数组。当该矩形是一个无效值时,返回nil
- (nullable __kindof UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath; // returns nil if cell is not visible or index path is out of range 某一分区的cell没如果改cell是不可见的或者indexPath超出了返回则返回nil
@property (nonatomic, readonly) NSArray<__kindof UITableViewCell *> *visibleCells; // 所有可见的cell,只读数组型(数组类型为UITableViewCell)
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForVisibleRows; // 所有可见行所在的分区,只读数组型(NSIndexPath)
- (nullable UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0); // 某一组的header视图(常用语自定义headerView用)
- (nullable UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0); // 某一组的footer视图(常用语自定义footerView用)
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated; //使表视图定位到某一位置(行)
- (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated; // 使表视图定位到选中行
Row insertion/deletion/reloading. 插入 删除 刷新
// 这两个方法,是配合起来使用的,标记了一个tableView的动画快。分别代表动画的开始和结束。两者成对出现,可以嵌套使用。一般,在添加,删除,选择tableView中使用,并实现动画效果。在动画快内,不建议使用reloadData方法,如果使用,会影响动画
- (void)beginUpdates; // allow multiple insert/delete of rows and sections to be animated simultaneously. Nestable 允许多个插入/行和段被同时删除动画。可排序
- (void)endUpdates; // only call insert/delete/reload calls or change the editing state inside an update block. otherwise things like row count, etc. may be invalid. 只调用插入/删除/重载呼叫或改变一更新区块内的编辑状态。然而对于行数等属性可能是无效的
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation; // 插入某些组
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation; // 删除某些组
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0); // 刷新某些组
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection NS_AVAILABLE_IOS(5_0); // 一定组section到组newSection的位置
- (void)insertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; // 插入某些行
- (void)deleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; // 删除某些行
- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0); // 刷新tableView指定行的数据
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath NS_AVAILABLE_IOS(5_0); // 移动分区indexPath的行到分区newIndexPath
Editing 编辑
/ Editing. When set, rows show insert/delete/reorder controls based on data source queries 编辑、设置之后,行的显示会基于数据源查询插入/删除/重排序的控制
@property (nonatomic, getter=isEditing) BOOL editing; // default is NO. setting is not animated. // 设置是否是编辑状态(编辑状态下的cell左边会出现一个减号,编辑右边会划出删除按钮)
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;
@property (nonatomic) BOOL allowsSelection NS_AVAILABLE_IOS(3_0); // default is YES. Controls whether rows can be selected when not in editing mode 当不再编辑模式时,是否可以选中,默认YES
@property (nonatomic) BOOL allowsSelectionDuringEditing; // default is NO. Controls whether rows can be selected when in editing mode 当处在编辑模式时,是否可以选中。默认NO
@property (nonatomic) BOOL allowsMultipleSelection NS_AVAILABLE_IOS(5_0); // default is NO. Controls whether multiple rows can be selected simultaneously 是否可以同时选中。默认NO
@property (nonatomic) BOOL allowsMultipleSelectionDuringEditing NS_AVAILABLE_IOS(5_0); // default is NO. Controls whether multiple rows can be selected simultaneously in editing mode 当处在编辑模式时,是否可以同时选中。默认NO
Selection 选中
@property (nonatomic, readonly, nullable) NSIndexPath *indexPathForSelectedRow; // returns nil or index path representing section and row of selection. 选中的行所在的分区(单选)
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForSelectedRows NS_AVAILABLE_IOS(5_0); // returns nil or a set of index paths representing the sections and rows of the selection. 选中的行所在的所有分区(多选)
// Selects and deselects rows. These methods will not call the delegate methods (-tableView:willSelectRowAtIndexPath: or tableView:didSelectRowAtIndexPath:), nor will it send out a notification. 代码收到选中与取消选中某行,注意:这两个方法将不会回调代理中的方法
- (void)selectRowAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;
Appearance 外观
@property (nonatomic) NSInteger sectionIndexMinimumDisplayRowCount; // show special section index list on right when row count reaches this value. default is 0 设置索引栏最小显示行数。先在右侧专门章节索引列表当行数达到此值。默认值是0
@property (nonatomic, strong, nullable) UIColor *sectionIndexColor NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR; // color used for text of the section index 设置索引栏字体颜色
@property (nonatomic, strong, nullable) UIColor *sectionIndexBackgroundColor NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; // the background color of the section index while not being touched 设置索引栏背景颜色
@property (nonatomic, strong, nullable) UIColor *sectionIndexTrackingBackgroundColor NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR; // the background color of the section index while it is being touched 设置索引栏被选中时的颜色
@property (nonatomic) UITableViewCellSeparatorStyle separatorStyle __TVOS_PROHIBITED; // default is UITableViewCellSeparatorStyleSingleLine 设置分割线的风格
typedef NS_ENUM(NSInteger, UITableViewCellSeparatorStyle) {
UITableViewCellSeparatorStyleNone,
UITableViewCellSeparatorStyleSingleLine,
UITableViewCellSeparatorStyleSingleLineEtched // This separator style is only supported for grouped style table views currently
} __TVOS_PROHIBITED;
@property (nonatomic, strong, nullable) UIColor *separatorColor UI_APPEARANCE_SELECTOR __TVOS_PROHIBITED; // default is the standard separator gray 设置分割线颜色
@property (nonatomic, copy, nullable) UIVisualEffect *separatorEffect NS_AVAILABLE_IOS(8_0) UI_APPEARANCE_SELECTOR __TVOS_PROHIBITED; // effect to apply to table separators 设置分割线毛玻璃效果(iOS8之后可用)
@property (nonatomic) BOOL cellLayoutMarginsFollowReadableWidth NS_AVAILABLE_IOS(9_0); // if cell margins are derived from the width of the readableContentGuide.
@property (nonatomic, strong, nullable) UIView *tableHeaderView; // accessory view for above row content. default is nil. not to be confused with section header 设置tableView头视图
@property (nonatomic, strong, nullable) UIView *tableFooterView; // accessory view below content. default is nil. not to be confused with section footer 设置tableView尾视图
- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one. 从复用池张取cell
- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); // newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered 获取一个已注册的cell
- (nullable __kindof UITableViewHeaderFooterView *)dequeueReusableHeaderFooterViewWithIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0); // like dequeueReusableCellWithIdentifier:, but for headers/footers 从复用池获取头视图或尾视图
注册cell
// Beginning in iOS 6, clients can register a nib or class for each cell.
// If all reuse identifiers are registered, use the newer -dequeueReusableCellWithIdentifier:forIndexPath: to guarantee that a cell instance is returned.
// Instances returned from the new dequeue method will also be properly sized when they are returned.
- (void)registerNib:(nullable UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0); // 通过xib文件注册cell
- (void)registerClass:(nullable Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0); // 通过oc类注册cell
- (void)registerNib:(nullable UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0); // 通过xib文件注册头视图和尾视图
- (void)registerClass:(nullable Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0); // 通过OC类注册头视图和尾视图
Focus 焦点
@property (nonatomic) BOOL remembersLastFocusedIndexPath NS_AVAILABLE_IOS(9_0); // defaults to NO. If YES, when focusing on a table view the last focused index path is focused automatically. If the table view has never been focused, then the preferred focused index path is used.
UITableViewDataSourceUITableView
需要一个数据源(dataSource)来显示数据,UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等。没有设置数据源的UITableView只是个空壳。凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源。
@protocol UITableViewDataSource<NSObject>
![
屏幕快照 2017-03-31 下午1.16.12.png
)
必须实现的
@required
// 每个section下cell的个数(必须实现)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
// 通过Indexpath返回具体的cell(必须实现)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
协议
返回有多少个section(默认是1)
// 返回有多少个section(默认是1)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; // Default is 1 if not implemented
每个section上面的标语内容
// 每个section上面的标语内容
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; // fixed font style. use custom view (UILabel) if you want something different
// 每个section下面的标语内容
- (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
// Editing
// 是否可编辑
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
// Moving/reordering
// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
// 是否可拖拽
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
// Index
// 右侧索引条需要的数组内容
- (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView __TVOS_PROHIBITED; // return list of section titles to display in section index view (e.g. "ABCD...Z#")
// 索引值对应的section-index
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index __TVOS_PROHIBITED; // tell table which section corresponds to section title/index (e.g. "B",1))
// Data manipulation - insert and delete support
// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
// Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead
// 对Cell编辑后的回调
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
// Data manipulation - reorder / moving support
// 对Cell拖拽后的回调
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
UITableViewDataSourcePrefetching(ios 10.0)
@required
// indexPaths are ordered ascending by geometric distance from the table view
- (void)tableView:(UITableView *)tableView prefetchRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
@optional
// indexPaths that previously were considered as candidates for pre-fetching, but were not actually used; may be a subset of the previous call to -tableView:prefetchRowsAtIndexPaths:
- (void)tableView:(UITableView *)tableView cancelPrefetchingForRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
类方法
// 类方法
+ (instancetype)indexPathForRow:(NSInteger)row inSection:(NSInteger)section;
@property (nonatomic, readonly) NSInteger section; // indexPath的组
@property (nonatomic, readonly) NSInteger row; // indexPath的行
补充
/*
----dataSource/delegate方法大概执行顺序(所有方法均实现):
1).numberOfSectionsInTableView;有多少section,例如k;
2).tableView:estimatedHeightForHeaderInSection + tableView:estimatedHeightForFooterInSection;计算k-1 section的header、footer大概高度;
3).tableView:numberOfRowsInSection;k-1 section有多少 row;
4).tableView:estimatedHeightForRowAtIndexPath;计算k-1 section中所有row的大概高度;
5).重复1)~4)步骤,直到所有0至k-1的section计算完;
6).sectionIndexTitlesForTableView;索引titles;
7).tableView:heightForRowAtIndexPath;依次计算visible区域(屏幕区域)里每个cell的高度(这里的所有cell记做集合A,决定于屏幕高度和estimatedHeightForXXX方法)
8).tableView:cellForRowAtIndexPath;创建第一个indexPath上的cell
9).tableView:indentationLevelForRowAtIndexPath; indexPath上的cell的缩进;
10).tableView:canEditRowAtIndexPath; indexPath上的cell编辑属性;
11).tableView:willDisplayCell:forRowAtIndexPath; indexPath上的cell将要显示;
12),重复8)~11),直到所有visible区域cell(集合A)创建完毕;
13).tableView:heightForHeaderInSection + tableView:heightForFooterInSection + tableView:viewForHeaderInSection + tableView:viewForHeaderInSection;依次计算visible区域里所有section 的header高度、footer高度、viewForHead、viewForFooter;
----执行顺序(没有实现estimatedHeight这些方法):
1).numberOfSectionsInTableView;有多少section,例如k;
2).tableView:heightForHeaderInSection + tableView:heightForFooterInSection;计算k-1 section的header、footer高度;
3).tableView:numberOfRowsInSection;k-1 section有多少 row;
4).tableView:heightForRowAtIndexPath;计算k-1 section中所有row得高度;
5).重复1)~4)步骤,直到所有0至k-1的section计算完
6).sectionIndexTitlesForTableView;索引titles;
7).tableView:cellForRowAtIndexPath;创建第一个indexPath上的cell
8).tableView:indentationLevelForRowAtIndexPath; indexPath上的cell的缩进;
9).tableView:canEditRowAtIndexPath; indexPath上的cell编辑属性;
10).tableView:willDisplayCell:forRowAtIndexPath; indexPath上的cell将要显示;
12).重复7)~12),知道所有visible区域(屏幕)cell创建完毕;
13).tableView:viewForHeaderInSection + tableView:viewForHeaderInSection;依次计算visible区域里所有的viewForHead、viewForFooter;
备注:
1.由上可看出,estimatedHeight在加载tableview的时候代替了heightFor方法,heightFor方法只有当cell需要显示的时候,才会调用。
2.关于estimatedHeightForXXX相关方法,里面的返回值并不能随意填写的,应该是真实高度的大概值;因为在加载tableview的时候,当所有的section header/footer row的高度都大概计算完,开始计算高度、并创建visible区域的cell时候,这些cell属不属于visible区域的判断依据就是之前的estimatedHeightForXXX方法返回的值算出来的;例如estimatedHeightForXXX相关方法返回值过大,算出来当前visible(屏幕)区域,包含3个section header 、footer以及里面的row,所以实际创建的时候也是创建这些cell(参考上文中方法执行顺序),当这些cell创建完,实际情况高度(heightForXXX方法所得)可能只占visible(屏幕)区域的一半,导致屏幕另一半空白。注意visible区域初始显示的cell是由estimatedHeightForXXX相关方法决定的,而不是heightForXXX这些方法真实高度决定的,所以有时tableview中visible区域尾部cell显示不出来或者创建的cell比visible区域cell多,都是estimatedHeightForXXX和heightForXXX方法相差导致的原因。
3.以上方法和ViewController那些方法关系:先执行viewdidload、willAppear等相关方法,再执行numberOfSectionsInTableView系列方法。
*/
详谈属性设置readwrite、readonly、retain、copy、assign、nonatomic
copy、retain、weak、assign
非ARC
• 1> copy : 只用于NSString\block
• 2> retain : 除NSString\block以外的OC对象
• 3> assign : 基本数据类型、枚举、结构体(非OC对象),当2个对象相互引用,一端用retain,一端用assign
•2.ARC
• 1> copy : 只用于NSString\block
• 2> strong : 除NSString\block以外的OC对象
• 3> weak : 当2个对象相互引用,一端用strong,一端用weak
4> assgin : 基本数据类型、枚举、结构体(非OC对象)
atomic,nonatomic
•1.atomic:设置成员变量的@property属性时,默认为atomic,提供多线程安全。
•2.nonatomic:禁止多线程,变量保护,提高性能。
atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。
__nonnull、nonnull
他们的作用是...
修饰一个属性的值,或者参数不能为空...
使用的方法和nullable一样
区别
1 . 可读性: readonly、readwrite
@property(readwrite,....) valueType value;
这个属性是变量的默认属性,就是如果你 (readwrite and readonly 都没有使用,那么你的变量就是 readwrite属性 ) ,通过加入 readwrite 属性你的变量就会有 get 和 set 方法。
property(readonly,...) valueType value;
这个属性变量就是表明变量只有可读方法,也就是说,你只能使用它的 get 方法。
2 . assign , setter 方法直接赋值,不进行任何 retain 操作,为了解决原类型与环循引用问题
3 . retain , setter 方法对参数进行 release 旧值再 retain 新值,所有实现都是这个顺序
4 . copy ,setter 方法进行 Copy 操作,与 retain 处理流程一样,先旧值 release ,再 copy 出新的对象,retainCount 为 1 。这是为了减少对上下文的依赖而引入的机制。
5 .nonatomic ,非原子性访问,不加同步,多线程并发访问会提高性能。
注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级 。 所以不加nonatomic 对与多线程是安全的 。
6 . retain vs. Copy
copy :建立一个索引计数为 1 的对象,然后释放旧对象
retain :释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为 1
那上面的是什么该死的意思呢?
copy 其实是建立了一个相同的对象,而 retain 不是
修改readonly的属性
修饰词
1getter=isOn
问题:
@property(nonatomic,getter=isOn) BOOL on; 中的getter = isOn的含义?
2 答案:
如果这个property是 BOOL on, 那么Objc默认创建的 setter 为: - (void)on:(BOOL)setOn { } getter 为: - (BOOL)on { return on; } 但是你可以手动更改 setter 和 getter 方法,就像上面的: getter = xxxOn 的话, getter 就变为: - (BOOL)xxxOn { return on; }
- (nullable NSArray<NSString *> *) (__kindof UITableViewCell *)
__kindof关键字的好处在于更加明确了以前id类型无法清晰表达的短板
- (__kindof UITableViewCell *)
表明方法返回的是UITableViewCell或其子类型,比以前的id类型更清晰,更明确。
对了,强制类型转换,泛型也涉及到强制类型转换问题,NSArray<__covariant ObjectType>,其中__covariant关键字就是表达可以 stringArray = mutStringArray,假如这样定义数组NSArray<ObjectType>,那stringArray = mutStringArray也会有警告(可以自定义类实现泛型验证),与__covariant对应的是__contravariant,如果这样定义数组NSArray<__contravariant ObjectType>,那么mutStringArray = stringArray;也不会有警告了,但这明显不合理。关于__covariant与__contravariant就不翻译了(有时候翻译真不如英文原版)
注1:参考NSDictionary头文件定义,来思考多参数泛型实现。
- (nullable NSArray<NSString *> *) (__kindof UITableViewCell *)
UITableView的数据源(dataSource)和代理(delegate)
UITableView需要一个数据源(dataSource)来显示数据,UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等。没有设置数据源的UITableView只是个空壳。凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源。
通常都要为UITableView设置代理对象(delegate),以便在UITableView触发一下事件时做出相应的处理,比如选中了某一行。凡是遵守了UITableViewDelegate协议的OC对象,都可以是UITableView的代理对象。一般会让控制器充当UITableView的dataSource和delegate
删除选中UITableView的行
首先要开启编辑模式
实现UITableViewDataSource的如下方法:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// 如果UITableView提交的是删除指令
if (editingStyle == UITableViewCellEditingStyleDelete) {
// 删除真实数据
// [self.data removeObjectAtIndex:indexPath.row];
// 删除UITableView中的某一行(带动画效果)
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
// 如果不考虑动画效果,也可以直接[tableView reload];
}
}
移动UITableView的行
首先要开启编辑模式
实现UITableViewDataSource的如下方法(如果没有实现此方法,将无法换行)
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
int from = sourceIndexPath.row;
int to = destinationIndexPath.row;
if (from == to) return;
// 交换数据
// [self.data exchangeObjectAtIndex:from withObjectAtIndex:to];
}
选中UITableView的行
当某行被选中时会调用此方法(UITableViewDelegate的方法)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//取消选中某一行,让被选中行的高亮颜色消失(带动画效果)
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
网友评论