UITableView-iOS-Apple官方文档翻译注释总结

易星纬
2023-12-01
<span style="font-size:18px;">//
//  UITableView.h
//  UIKit
//
//  Copyright (c) 2005-2015 Apple Inc. All rights reserved.
//


#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIScrollView.h>
#import <UIKit/UISwipeGestureRecognizer.h>
#import <UIKit/UITableViewCell.h>
#import <UIKit/UIKitDefines.h>

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, UITableViewStyle) {
    UITableViewStylePlain,          // regular table view       普通类型
    UITableViewStyleGrouped         // preferences style table view     分组类型
};

// scrollPosition参数决定定位的相对位置
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

// 行变化(插入、删除、移动的动画类型)
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        // 自动选择合适的动画
};

// Including this constant string in the array of strings returned by sectionIndexTitlesForTableView: will cause a magnifying glass icon to be displayed at that location in the index.
// This should generally only be used as the first title in the index.
UIKIT_EXTERN NSString *const UITableViewIndexSearch NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;

// Returning this value from tableView:heightForHeaderInSection: or tableView:heightForFooterInSection: results in a height that fits the value returned from
// tableView:titleForHeaderInSection: or tableView:titleForFooterInSection: if the title is not nil.
UIKIT_EXTERN const CGFloat UITableViewAutomaticDimension NS_AVAILABLE_IOS(5_0);

@class UITableView;
@class UINib;
@protocol UITableViewDataSource;
@class UILongPressGestureRecognizer;
@class UITableViewHeaderFooterView;
@class UIRefreshControl;
@class UIVisualEffect;

typedef NS_ENUM(NSInteger, UITableViewRowActionStyle) {
    UITableViewRowActionStyleDefault = 0,
    UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault,
    UITableViewRowActionStyleNormal
} NS_ENUM_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

NS_CLASS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED @interface UITableViewRowAction : NSObject <NSCopying>

+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(nullable NSString *)title handler:(void (^)(UITableViewRowAction *action, NSIndexPath *indexPath))handler;

@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;

@end

NS_CLASS_AVAILABLE_IOS(9_0) @interface UITableViewFocusUpdateContext : UIFocusUpdateContext

@property (nonatomic, strong, readonly, nullable) NSIndexPath *previouslyFocusedIndexPath;
@property (nonatomic, strong, readonly, nullable) NSIndexPath *nextFocusedIndexPath;

@end

//_______________________________________________________________________________________________________________
// this represents the display and behaviour of the cells.          这边是cell的显示和行为

@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>

@optional

// 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.
// 设置行高,头视图高度和尾视图高度的估计值(对于高度可变的情况下,提高效率)
// https://www.shinobicontrols.com/blog/ios7-day-by-day-day-19-uitableview-row-height-estimation    //tableView估算高度网址
- (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 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) __TVOS_PROHIBITED;
// 设置每个单元格上面的按钮的点击方法
- (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.
// 当前选中的row是否高亮
- (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);
// 通知委托表视图的指定行不在高亮显示,一般是点击其他行的时候
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);

// Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
// cell选择和取消选择
- (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);
/* 先点击row1,再点击row2,两者执行顺序:在下一行将要选中后才取消上一行的选中
 willSelectRowAtIndexPath 当前row为:0
 didSelectRowAtIndexPath 当前row为:0
 willSelectRowAtIndexPath 当前row为:1
 willDeselectRowAtIndexPath 当前row为:0
 didDeselectRowAtIndexPath 当前row为:0
 didSelectRowAtIndexPath 当前row为:1
 */


// 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.
// 设置tableView被编辑时的状态风格,如果不设置,默认是删除风格
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
// 自定义删除按钮的标题
- (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;
// 用于自定义创建tableView被编辑时右边的按钮,按钮类型为UITableViewRowAction
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED; // supercedes -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: if return value is non-nil

// 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.
// 设置编辑模式下是否需要对表视图指定行进行缩进,NO为关闭缩进,这个方法可以用来去掉move时row前面的空白
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath;

// 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 __TVOS_PROHIBITED;
// 完成编辑后调用
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath __TVOS_PROHIBITED;

// Moving/reordering

// Allows customization of the target row for a particular row as it is being moved/reordered
// 移动特定的某行(注意区别之前的tableView:moveRowAtIndexPath:toIndexPath方法。当手指按住reorde accessory view移动时,只要有row moved/reordered都会调用该方法,而前者方法只有当手指放开reorder accessory view时,结束move/order操作才会调用自己。返回值代表进行移动操作后回到的行,如果设置为当前行,则不论怎么移动都会回到当前行)
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;               

// Indentation
// 行缩进
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath; // return 'depth' of row for hierarchies

// Copy/Paste.  All three methods must be implemented by the delegate.
// 长按出来的Copy/Paste操作 (复制粘贴)----->通知委托是否在指定行显示菜单,返回值为YES时,长按显示菜单
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(5_0);
// 弹出选择菜单时会调用此方法(复制、粘贴、全选、剪切)
- (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 焦点

- (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);

@end

UIKIT_EXTERN NSString *const UITableViewSelectionDidChangeNotification;     // 通知


//_______________________________________________________________________________________________________________

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITableView : UIScrollView <NSCoding>

- (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;     // 列表视图的类型,只读
@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

@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这个方法常用语新加或者删除了索引类别二无需率先呢整个表视图的情况下

// 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. 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     设置分割线的风格
@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     从复用池获取头视图或尾视图

// 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.

@end

//_______________________________________________________________________________________________________________
// this protocol represents the data model object. as such, it supplies no information about appearance (including the cells)

@protocol UITableViewDataSource<NSObject>

@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;

@optional

// 返回有多少个section(默认是1)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;              // Default is 1 if not implemented

// 每个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

// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
// 是否可编辑
- (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;

@end

//_______________________________________________________________________________________________________________

// This category provides convenience methods to make it easier to use an NSIndexPath to represent a section and row
@interface NSIndexPath (UITableView)

// 类方法
+ (instancetype)indexPathForRow:(NSInteger)row inSection:(NSInteger)section;

@property (nonatomic, readonly) NSInteger section;      // indexPath的组
@property (nonatomic, readonly) NSInteger row;          // indexPath的行

@end

NS_ASSUME_NONNULL_END</span>







一般执行顺序如下:

<span style="font-size:18px;">/*
 ----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系列方法。
 */</span>


UItableView用法总结

<span style="font-size:24px;">UITableView</span>

<span style="font-size:14px;">UITableView内置了两种样式:UITableViewStylePlain,UITableViewStyleGrouped

<UITableViewDataSource,UITableViewDelegate]] > 里的方法:
tableView处理步骤
#pragma mark 1.有多少组
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
#pragma mark 2.第section组头部控件有多高
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
#pragma mark 3.第section组有多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
#pragma mark 4.indexPath这行的cell有多高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
#pragma mark 5.indexPath这行的cell长什么样子
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
#pragma mark 6.第section组头部显示什么控件
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

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

//每当有一个cell进入视野屏幕就会调用,所以在这个方法内部就需要优化。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if(cell==nil){
//在这里面做创建的工作。循环优化。防止刷新cell进入屏幕的时候重复的创建
}
}

//当调用reloadData的时候,会重新刷新调用数据源内所有方法,其他事情都不会做呀
 [self reloadData]

 //这个方法只有在一开始有多少条数据才会算多少个高度,这个方法只会调用一次,但是每次reloadData的时候也会调用
 //而且会一次性算出所有cell的高度,比如有100条数据,一次性调用100次
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath



-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView //右侧索引

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath //行点击事件

NSIndexPath *path = [self.tableView indexPathForSelectedRow]; //获得被选中的indexPath可以得到section,row
  
[self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForSelectedRows] withRowAnimation:UITableViewRowAnimationNone]; //刷新table指定行的数据
        
[self.tableView reloadData]; //刷新table所有行的数据


UITableView常用属性:
    UITableView *tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 460) style:UITableViewStylePlain]; // 初始化表格
    分隔线属性 
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; //UITableViewCellSeparatorStyleNone;
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone]; //取消分隔线
    tableView.separatorColor = [UIColor lightGrayColor];
   
    条目多选
tableView.allowsMultipleSelection = YES;
    
    // 设置标题行高
    [_tableView setSectionHeaderHeight:kHeaderHeight];
    [_tableView setSectionFooterHeight:0];

    // 设置表格行高
    [_tableView setRowHeight:50];

//设置背景色
self.tableView.backgroundView  优先级高,如果要设置backgroundColor的时候要先把view设置为nil
self.tableView.backgroundColor

//在tableView的头部或者尾部添加view,footerView宽度是不用设置的
    xxxView.bounds = CGRectMake(0,0,0,height);
    self.tableView.tableFooterView =xxxView;
    self.tableView.tableHeaderView =xxxView;

UIButton *bt = (UIButton*)[self.contentView viewWithTag:i+100];
 
增加tableview滚动区域
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, xx, 0); </span>



<span style="font-size:24px;">UITableViewCell</span>
<span style="font-size:14px;">
//创建UITableViewCell        
UITableViewCell *cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
       
[cell.textLabel setBackgroundColor:[UIColor clearColor]];// 清空标签背景颜色 
       
        cell.backgroundView =xx; //设置背景图片
        cell.backgroundVColor =xx;
        cell.selectedBackgroundView = selectedBgView; //设置选中时的背景颜色

      
   cell.accessoryView = xxxView; //设置右边视图
   [cell setAccessoryType:UITableViewCellAccessoryNone]; //设置右侧箭头
 
[self setSelectionStyle:UITableViewCellSelectionStyleNone]; //选中样式
cell.selectionStyle = UITableViewCellSelectionStyleBlue;

//设置cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

contentView下默认有3个子视图,其中的2个是UILabel,通过textLabel和detailTextLabel属性访问,第3个是UIImageView,通过imageView属性访问.
  UITableViewCellStyleDefault, UITableViewCellStyleValue1, UITableViewCellStyleValue2, UITableViewCellStyleSubtitle
 
#pragma mark - 重新调整UITalbleViewCell中的控件布局
- (void)layoutSubviews{
[super layoutSubviews];
…
}</span>

<strong><span style="font-size:24px;">UITableViewCell表格优化</span>
<span style="font-size:18px;">UITableViewCell对象的重用原理:
重用原理:当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回UITableViewCell时,dataSource会先查看这个对象池,如果池中有未使用的UITableViewCell,dataSource会用新的数据配置这个UITableViewCell,然后返回给UITableView,重新显示到窗口中,从而避免创建新对象
还有一个非常重要的问题:有时候需要自定义UITableViewCell(用一个子类继承UITableViewCell),而且每一行用的不一定是同一种UITableViewCell(如短信聊天布局),所以一个UITableView可能拥有不同类型的UITableViewCell,对象池中也会有很多不同类型的UITableViewCell,时可能会得到错误类型的UITableViewCell那么UITableView在重用UITableViewCell。解决方案:UITableViewCell有个NSString *reuseIdentifier属性,可以在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(一般用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先通过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,如果有,就重用,如果没有,就传入这个字符串标识来初始化一个UITableViewCell对象
</span></strong>
<span style="font-size:14px;">/**
单元格优化
 1. 标示符统一,使用static的目的可以保证表格标示符永远只有一个
 2. 首先在缓冲池中找名为"myCell"的单元格对象
 3. 如果没有找到,实例化一个新的cell
 **/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *cellIdentifier = @"myCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
//使用这种方法不用判断下面的cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    if (cell == nil) {       
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
return cell;
}</span>

<strong><span style="font-size:24px;">表格的编辑模式</span></strong>
<span style="font-size:14px;">//删除、插入 
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;  开启表格编辑状态 

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
返回表格编辑编辑样式。不实现默认都是删除
return editingStyle : UITableViewCellEditingStyleDelete, UITableViewCellEditingStyleInsert
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
  //根据editingStyle处理是删除还是添加操作
  完成删除、插入操作刷新表格
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

-(void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
}

//移动
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
//sourceIndexPath 移动的行
//destinationIndexPath 目标的行</span>

<strong><span style="font-size:24px;">自定义表格行UITableViewCell</span></strong>
<span style="font-size:14px;">storyboard方式创建:
直接拖到UITableView里面设置UITableViewCell
注意:
1.通过XIB或者Storyboard自定义单元格时,在xib和Storyboard里面需要指定单元格的可重用标示符Identifier

2.注意表格的优化中的差别
在Storyboard中两者等效
xxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
xxCell *cell1 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

在xib文件中有差别:
第一种情况,只能在iOS 6以上使用,如果在viewDidLoad注册了nib文件,并且指定了“单元格”的可重用标示符,那么    
     dequeueReusableCellWithIdentifier:
     dequeueReusableCellWithIdentifier:forIndexPath:
     方法是等效的。如果在viewDidLoad中注册了nib文件,表格缓冲池中的管理,有系统接管!

第二种情况,是在iOS 4以上均可以使用,如果没有在viewDidLoad注册nib文件,那么,只能使用
     dequeueReusableCellWithIdentifier:并且需要判断cell没有被实例化,并做相应的处理

 
在代码创建中差别:
用代码创建cell中的处理和nib一样,注册了cell就有系统接管并且可以用带forIndexPath的方法,没有注册就要自己去实例化cell,不能用带forIndexPath的方法
[tableView registerClass:XxxCell class] forCellReuseIdentifier:@"xxCell"];

xib方式创建:
//注册Identifier 
- (void)viewDidLoad{
    [super viewDidLoad];
    /**

//转载请注明出处--本文永久链接:http://www.cnblogs.com/ChenYilong/p/3495919.html


     注意:以下几句注册XIB的代码,一定要在viewDidLoad中!
     注册XIB文件,获得根视图,并且转换成TableView,为tableView注册xib
     Identifier名要在xib文件中定义,并且保持一致
     **/
    UINib *nib = [UINib nibWithNibName:@"BookCell" bundle:[NSBundle mainBundle]];
    UITableView *tableView = (UITableView *)self.view;
    [tableView registerNib:nib forCellReuseIdentifier:@"bookCell"];   
}

//没有注册Identifier只能使用下面方法
static NSString *CellIdentifier = @"bookCell";
BookCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
        cell = [[BookCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        NSBundle *bundle = [NSBundle mainBundle];
        NSArray *array = [bundle loadNibNamed:@"BookCell" owner:nil options:nil];
        cell = [array lastObject];
    }


代码方式创建:
建立UITableViewCell的类,继承UITableViewCell
往cell里面加入view的时候注意点:
//新建的组件放入contentView中
[self.contentView addSubview:xxView]; 

//设置图片拉伸属性stretch
UIImage *normalImage = [UIImage imageNamed:@"xx.png"];
normalImage = [normalImage stretchableImageWithLeftCapWidth:
normalImage.size.width / 2 topCapHeight:normalImage.size.height / 2];

//在tableView里面viewDiDLoad里面要注册cell类
[tableView registerClass:XxxCell class] forCellReuseIdentifier:@"xxCell"];</span>

<strong><span style="font-size:24px;">自定义表格中Header</span></strong>
<span style="font-size:14px;">//自定义表格在这个方法中定义
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section</span>





 类似资料: