iOS:UITableView 方法 屬性 詳解
參考:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html <UITableView Class Reference> + UITableView.h
簡介:
--一個@的例項意味著展示和編輯分層列表的資訊。一個tableview在一欄中展示了一系列item,它是UIScrollview的子類,允許使用者在列表上滑動,但只能是垂直方向。
--tableview有倆種樣式,見下圖:
==================datasource方法
==================delegate方法==================@required - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; @optional // Default is 1 if not implemented - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; //每個section的title - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section; //每個section的footer // Editing/Moving or Reordering // 不同的row可以有同的-editing屬性。當row的editing屬性為NO,則它不可編輯(tableview setEditing改變的時候它沒影響);為YES時,可編輯,可以有不同的editingStyle,詳見"editingStyleForRowAtIndexPath方法"。Default is YES; - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath; // 不同的row是否可以移動。當tableview處於editing狀態時:如果某個row返回值為NO,則它的reorder accessory view不會顯示,不可移動;如果某個row的返回值為YES的時候,且datasource有實現-tableView:moveRowAtIndexPath:toIndexPath:方法,則顯示該row的reorder accessory view 可以移動,否則還是不顯示reorder accessory view,不可移動; - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath; // Index //返回list of section titles to display in section index view (e.g. "ABCD...Z#") - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView; // which section corresponds to sectionIndexTitle,當點選某個sectionIndexTitle時候,返回某個section的值,tableview就移動到該section; - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index; // Data manipulation - insert and delete / reorder or moving support // 當tableview處於editing狀態時,如果row可編輯,則會has the minus or plus button invoked(based on the UITableViewCellEditingStyle for the cell)。當點選minus or plus button的時候,就會呼叫該方法(如果是minus button,需要點選到隨後的delete才會觸發方法); - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath; // 當tableview處於editing狀態,並且row可以canMove,如果拖動某row換行,則呼叫改方法; - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath; @end
@optional // Display customization - (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); - (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 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section; - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section; // tableview在每次reload data時都會要所有cell的高度,這非常影響程式效能,使用estimatedHeight methods to quickly calcuate guessed values 去快速載入tableview // 原理: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); // Section header & footer information. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section; //custom view for header. will be adjusted to default or specified header height - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section; //custom view for footer. will be adjusted to default or specified footer height // Accessories (disclosures). // 當cell的accessaryType為UITableViewCellAccessoryDetailDisclosureButton時,點選accessaryView將會呼叫delegate的tableView:accessoryButtonTappedForRowWithIndexPath方法。否則只是didSelectRowAtIndexPath; - (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 or YES 當前選中的row是否高亮 - (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); - (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. /* 先點選row1,再點選row2,倆著執行順序:在下一行將要選中後才取消上一行的選中 willSelectRowAtIndexPath 當前row為:0 didSelectRowAtIndexPath 當前row為:0 willSelectRowAtIndexPath 當前row為:1 willDeselectRowAtIndexPath 當前row為:0 didDeselectRowAtIndexPath 當前row為:0 didSelectRowAtIndexPath 當前row為:1 */ - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath; - (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 // 允許cell自定義editingStyle.Default is UITableViewCellEditingStyleDelete(when the table has editing property set to YES) - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath; // 當tableview editing為YES,點選minus時出來deleteButton的title.Default is 'Delete'; - (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0); // 當tableview處於編輯時,控制row的background是否is indented就是row所在的那個框,例如縮不縮排可能會導致左邊的edit按鈕是在row框裡面or外面)。Default is YES.(方法僅僅適用於grouped style 且跟之後的indentation level 方法沒有關係) - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath; // 方法被調whenever the 'editing' property is automatically changed by the table (allowing insert/delete/move). 注意,如果是tableview的'editing'改變,方法不會呼叫。只有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 // 注意區別之前的tableView:moveRowAtIndexPath:toIndexPath方法。當手指按住reorder 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; //不同row的縮排 // 長按出來的Copy/Paste操作 - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(5_0); - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender NS_AVAILABLE_IOS(5_0); - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender NS_AVAILABLE_IOS(5_0); @end
----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系列方法。
==================屬性、方法==================
@屬性 CGFloat rowHeight;sectionHeaderHeight;sectionFooterHeight; //類似相應方法,只不過是個統一值
@屬性 CGFloat estimatedRowHeight; estimatedSectionHeaderHeight;estimatedSectionFooterHeight NS_AVAILABLE_IOS(7_0); //類似相應方法,只不過是個統一值
@屬性 UIView *backgroundView ; //the background view will be automatically resized to track the size of the table view.
@屬性 UIEdgeInsets separatorInset NS_AVAILABLE_IOS(7_0) ; //allows customization of the frame of cell separators 測試發現僅UIEdgeInsets中的right、left起作用
// 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.
// Info
- (NSInteger)numberOfSections;
- (NSInteger)numberOfRowsInSection:(NSInteger)section;
- (CGRect)rectForSection:(NSInteger)section; // includes header, footer and all rows
- (CGRect)rectForHeaderInSection:(NSInteger)section;
- (CGRect)rectForFooterInSection:(NSInteger)section;
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath;
- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point; // returns nil if point is outside of any row in the table
- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell; // returns nil if cell is not visible
- (NSArray *)indexPathsForRowsInRect:(CGRect)rect; // returns nil if rect not valid
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath; // returns nil if cell is not visible or index path is out of range
- (NSArray *)visibleCells;
- (NSArray *)indexPathsForVisibleRows;
- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
- (UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
// 滾動row identified by index path到特殊位置
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
// 滾動table使得selected row nearest to a specified position
- (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.
- (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);
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath NS_AVAILABLE_IOS(5_0);
// 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.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;
@屬性 BOOL allowsSelection;allowsSelectionDuringEditing; allowsMultipleSelection;allowsMultipleSelectionDuringEditing;
// Selection
- (NSIndexPath *)indexPathForSelectedRow; // returns nil or index path representing section and row of selection.
- (NSArray *)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:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;
// Appearance
@屬性 NSInteger sectionIndexMinimumDisplayRowCount;//當tableView中多少行的時候開始顯示IndexList,預設的設定是NSIntegerMax,即預設是不顯示indexList的
@屬性 UIColor *sectionIndexColor; sectionIndexBackgroundColor; sectionIndexTrackingBackgroundColor;
@property(nonatomic) UITableViewCellSeparatorStyle separatorStyle; // default is UITableViewCellSeparatorStyleSingleLine
@property(nonatomic,retain) UIColor *separatorColor; // default is the standard separator gray
@property(nonatomic,retain) UIView *tableHeaderView; tableFooterView;
//Reusable 重用
/*
A:UITableView標頭檔案,會找到NSMutableArray* visiableCells,和NSMutableDictnery* reusableTableCells兩個結構。visiableCells內儲存當前顯示的cells,reusableTableCells儲存可重用的cells;
B:TableView顯示之初,reusableTableCells為空,那麼tableView dequeueReusableCellWithIdentifier:CellIdentifier返回nil。開始的cell都是通過[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]來建立,而且cellForRowAtIndexPath只是呼叫最大顯示cell數的次數;
例如:有100條資料,iPhone一屏最多顯示10個cell。程式最開始顯示TableView的情況是:
1. 用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]建立10次cell,並給cell指定同樣的重用標識(當然,可以為不同顯示型別的cell指定不同的標識)。並且10個cell全部都加入到visiableCells陣列,reusableTableCells為空。
2. 向下拖動tableView,當cell1完全移出螢幕,並且cell11(它也是alloc出來的,原因同上)完全顯示出來的時候。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。
3. 接著向下拖動tableView,因為reusableTableCells中已經有值,所以,當需要顯示新的cell,cellForRowAtIndexPath再次被呼叫的時候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。cell1加入到visiableCells,cell1移出reusableTableCells(測試發現cell1會被移出,而不是還留在reusableTableCells中複用);cell2移出visiableCells,cell2加入到reusableTableCells。之後再需要顯示的Cell就可以正常重用了。
*/
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier; // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one.
- (id)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
- (id)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:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
- (void)registerNib:(UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
- (void)registerClass:(Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
// 關於:倆種dequeueReusableCellWithIdentifier 方法的區別:
1.一個6.0才能使用的方法;
2.使用6.0新方法的前提是,必須使用配套的register 相關方法,例如:
[_tableView registerClass:[MXCustomCell class] forCellReuseIdentifier:CellIdentifier];
_tableView.dataSource = self;
_tableView.delegate = self;
[self.view addSubview:self.notNib_tableView];
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:@"6.0方法 %d", indexPath.row];
return cell;
}
3.用處:to dequeue your cell, it will be the right size and you'll be able to do layout inside your cell's contentView
備註:--參考:http://blog.sina.com.cn/s/blog_6fd90b5b0101705h.html
----1.tableview 中cell的reordering示意圖:
----2.tableview中cell的delete & insert操作示意圖:
注:
一.在tableview執行deleteRow/insertRow類似操作時,tableview介面更新時,並沒有reloadData,而是:
a.estimatedHeightFor每個section的header、footer、row;
b.計算visible區域每個cell的heightForRowAtIndexPath;
c.新新增的/新進入visible區域(刪除)cell的cellForRowAtIndexPath方法;以及cell的indentationLevel、canEdit、canMove、editStyle、willDisplay等方法;
d.heightFor剩下/其餘的row、section的header、footer;(c和d的順序不同情況可能會調換)
----3.批量插入,刪除,部分更新操作:UITableView提供了一個批量操作的特性,這個功能在一次進行多個row或者scetion的刪除,插入,獲取更新多個cell內容的時候特別好用。所有的批量操作需要包含在beginUpdates和endUpdates塊中,否則會出現異常。操作順序如下圖:
注意:在批量操作時,不管程式碼中先寫的新增操作還是刪除操作,新增操作都會被推出執行,直到這個塊中所有的刪除操作都執行完以後,才會執行新增操作。如上圖:首先刪除section 0中的row 1,然後刪除section 1,再向section 1中新增一行。執行完批量更新以後就得到右半邊的結果。
----4.reloadData的執行過程:跟tableview第一次載入執行過程一樣(參考上文"方法執行順序"),只不過它將所有visible區域的cell都放入reusableTableCells中,所以dequeueReusableCellWithIdentifier方法可重用cell。