UITableView
A view that presents data using rows arranged in a single column.
1.public init(frame: CGRect, style: UITableView.Style)
1.2 UITableView.Style
case plain
(Section headers and footers are displayed as inline separators and float when the table view is scrolled.)
Section會根據(jù)tableView的滾動(dòng) 然后懸浮在最上層
case grouped
(Section headers and footers do not float when the table view scrolls.)
2. weak open var dataSource: UITableViewDataSource?
2.1 UITableViewDataSource
2.1.1
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
(Tells the data source to return the number of rows in a given section of a table view.)
2.1.2
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
(
Asks the data source for a cell to insert in a particular location of the table view.
)
2.1.3
optional func numberOfSections(in tableView: UITableView) -> Int
(Asks the data source to return the number of sections in the table view.)
2.1.4
optional func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
(Asks the data source for the title of the header of the specified section of the table view.)
2.1.5
optional func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
(Asks the data source to verify that the given row is editable.)
(默認(rèn)都為true,但是如果為false 的行 就是 刪除 插入都不會再有動(dòng)畫 ,UITableViewCell.EditingStyle.none這個(gè)當(dāng)然也可以)
2.1.6
optional func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
(Asks the data source whether a given row can be moved to another location in the table view.)
By default, the reordering control is shown if the data source implements the tableView(_:moveRowAt:to:) method.
2.1.7
optional func sectionIndexTitles(for tableView: UITableView) -> [String]? // return list of section titles to display in section index view (e.g. "ABCD...Z#")
(右邊的ABCDEF…)
2.1.8
optional func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int
(點(diǎn)擊右邊的 跳到第幾個(gè).)
This method is passed the index number and title of an entry in the section index list and should return the index of the referenced section.
Note that the array of section titles returned by sectionIndexTitles(for:) can have fewer items than the actual number of sections in the table view.
2.1.9
optional func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
(Asks the data source to commit the insertion or deletion of a specified row in the receiver.)
When users tap the insertion (green plus) control or Delete button associated with a UITableViewCell object in the table view, the table view sends this message to the data source, asking it to commit the change. (If the user taps the deletion (red minus) control, the table view then displays the Delete button to get confirmation.) The data source commits the insertion or deletion by invoking the UITableView methods insertRows(at:with:) or deleteRows(at:with:), as appropriate.
(左滑,點(diǎn)擊刪除 插入 等等操作的時(shí)候 你怎么干 swipe-to-delete~)
To enable the swipe-to-delete feature of table views (wherein a user swipes horizontally across a row to display a Delete button), you must implement this method.
2.1.10
optional func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
(Tells the data source to move a row at a specific location in the table view to another location.)
Data manipulation - reorder / moving support
(應(yīng)該是其他的代理方法設(shè)置了 才在這邊可以執(zhí)行)
3. weak open var delegate: UITableViewDelegate?
(Methods for managing selections, configuring section headers and footers, deleting and reordering cells, and performing other actions in a table view.)
3.1 UITableViewDelegate
3.1.1
optional func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
(
Tells the delegate the table view is about to draw a cell for a particular row.
)
理解錯(cuò)誤了
what's the different between “cellForRowAtIndexPath” and “willDisplayCell: forRowAtIndexPath:”
1.兩者所處的代理方法不同,且一個(gè)必須執(zhí)行,一個(gè)是可選執(zhí)行
- willDisplayCell 在 cellForRowAtIndexPath之后執(zhí)行 是最后調(diào)整UI的機(jī)會, At this point, the cell instance has already been created.
So this way you supply the cell in cellForRowAtIndexPath and update the content in willDisplayCell
加載圖片和視頻最好是在willDisplayCell下進(jìn)行.因?yàn)?cellForRow 中 直接會把20張加載好 會有大量的實(shí)例請求.在 willDisplayCell 中 用戶可以看到哪實(shí)例請求到哪 所以willDisplayCell 可能會是更好的位置
The delegate method willDisplayCell will be called every time a cell is just about to get displayed on the screen. Say for example - you are downloading any image data, then this is the best place to do the download or call the method that downloads image data.
The problem with downloading image data in cellForRow or cellForItem is, a large number of images/photos comes back from the initial request. The user may never even scroll down far enough to see all of the images. This is very costly as it may eat up users cellular data.
So the big vote here for willDisplayCell is User may never scroll down, so why download all images in cellForRow?. Make use of willDisplayCell to only download those images user is about to see.
還有一種是播放視頻或者圖片的時(shí)候 在cell中 可以節(jié)省流量
I had an app where images and video would be loaded in from either a URLCache or downloaded and displayed in the cell. I noticed whenever I'd start my application all the videos and images would load before I could see them and I noticed this because I could hear the audio from the last video in the tableView while looking at the first item in the tableView. This is with 8 items in the tableView.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "feedCell", for: indexPath) as! FeedCell
print("Created cell at row \(indexPath.row)")
let post = posts[indexPath.row]
cell.post = post
cell.viewController = self
cell.configureCell()
return cell}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let feedCell = cell as? FeedCell{
print("Drew feed cell at row \(indexPath.row)")
// only want download task to start when the cell will display
if feedCell.post.isVideo {
feedCell.loadVideo()
} else {
feedCell.loadImage()
}
}
}
override func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
print("Stopped showing cell at row \(indexPath.row)")
if let feedCell = cell as? FeedCell{
feedCell.player?.pause()
}
}
(以上只是有人這么寫 自己具體還沒有試過)
3.1.2
optional func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)
3.1.3
optional func tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int)
3.1.4
optional func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath)
(
Tells the delegate that the specified cell was removed from the
table.
)
3.1.5
optional func tableView(_ tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int)
3.1.6
optional func tableView(_ tableView: UITableView, didEndDisplayingFooterView view: UIView, forSection section: Int)
3.1.7
optional func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
(
Asks the delegate for the height to use for a row in a specified location.
)
3.1.8
optional func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
3.1.9
optional func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
3.1.10
optional func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
Asks the delegate for the estimated height of a row in a specified location.
Using estimation allows you to defer some of the cost of geometry calculation from load time to scrolling time.
estimatedHeightForRowAt is not called on scroll
3.1.11
optional func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat
3.1.12
optional func tableView(_ tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat
3.1.13
optional func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
Asks the delegate for a view object to display in the header of the specified section of the table view.
3.1.14
optional func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
3.1.15
optional func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath)
Tells the delegate that the user tapped the detail button for the
specified row.
Use this method to respond to taps in the detail button
accessory view of a row. The table view does not call this
method for other types of accessory views.
問題1:還不知道在哪執(zhí)行這個(gè)方法
3.1.16
optional func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool
Asks the delegate if the specified row should be highlighted.
As touch events arrive, the table view highlights rows in anticipation of the user selecting them. As it processes those touch events, the table view calls this method to ask your delegate if a given cell should be highlighted. Your delegate can implement this method and use it to prevent the highlighting of a row when another row is already selected or when other relevant criteria occur.
If you do not implement this method, the default return value is true.
點(diǎn)中某一行的時(shí)候允不允許他highlighted
3.1.17
optional func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath)
Tells the delegate that the specified row was highlighted.
3.1.18
optional func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath)
Tells the delegate that the highlight was removed from the row at the specified index path.
3.1.19
optional func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath?
Tells the delegate that a specified row is about to be selected.
This method is not called until users touch a row and then lift their finger;
點(diǎn)的是哪個(gè) 返回indexPath 返回到 didSelectRowAt 中我們需要處理的 indexPath
3.1.20
optional func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
Tells the delegate that the specified row is now selected.
3.1.21
optional func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath?
Tells the delegate that a specified row is about to be deselected.
This method is only called if there is an existing selection
when the user tries to select a different row
3.1.22
optional func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
Tells the delegate that the specified row is now deselected.
以上的執(zhí)行
順序
didHighlightRowAt [0, 0]
didUnhighlightRowAt [0, 0]
willSelectRowAt [0, 0]
didSelectRowAt [0, 0]
didHighlightRowAt [0, 1]
didUnhighlightRowAt [0, 1]
willSelectRowAt [0, 1]
willDeselectRowAt [0, 0]
willDeselectRowAt [0, 0]
didDeselectRowAt [0, 0]
didSelectRowAt [0, 1]
很奇怪 willDeselectRowAt 會執(zhí)行2次
3.1.23
optional func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle
Asks the delegate for the editing style of a row at a particular location in a table view.
This method allows the delegate to customize the editing style of the cell located atindexPath. If the delegate does not implement this method and the UITableViewCell object is editable (that is, it has its isEditing property set to true), the cell has the UITableViewCell.EditingStyle.delete style set for it.
q:我返回了 UITableViewCell.EditingStyle.insert 但是沒有任何反應(yīng)
a:需要在tableView.isEditing 為true 的情況下才能使用
補(bǔ)充:
系統(tǒng)的
delete樣式 ,點(diǎn)擊會右邊劃出刪除按鈕
insert 樣式,點(diǎn)擊會執(zhí)行 commit editingStyle方法
若是 UITableViewCellEditingStyle.init(rawValue: 3) 系統(tǒng)無法區(qū)分,點(diǎn)擊無效果
如果想實(shí)現(xiàn)的話 還是自定義cell來的快
3.1.24
optional func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String?
Changes the default title of the delete-confirmation button.
改刪除按鈕上的文字
3.1.25
optional func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
Asks the delegate for the actions to display in response to a swipe in the specified row.
Use this method when you want to provide custom actions for one of your table rows. When the user swipes horizontally in a row, the table view moves the row content aside to reveal your actions. Tapping one of the action buttons executes the handler block stored with the action object.
If you do not implement this method, the table view displays the standard accessory buttons when the user swipes the row.
你想自定義側(cè)滑的時(shí)候的custom actions 就執(zhí)行這個(gè)方法
自定義 并且執(zhí)行方法
補(bǔ)充:
UITableViewRowAction
初始化方法 顏色 文字 都是可以調(diào)的
還有一個(gè)屬性
@NSCopying open var backgroundEffect: UIVisualEffect?
….
不知道干啥的
3.1.26 iOS 11
optional func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
左側(cè)滑動(dòng)自定義按鈕
3.1.27 iOS 11
optional func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
右側(cè)滑動(dòng)自定義按鈕
3.1.28
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool
Asks the delegate whether the background of the specified
row should be indented while the table view is in editing mode.
我們只要在委托方法 shouldIndentWhileEditingRowAt 中返回 false 即可嚼贡,表示關(guān)閉縮進(jìn)娶靡。
3.1.29
optional func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath)
Tells the delegate that the table view is about to go into editing mode.
3.1.30
optional func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?)
Tells the delegate that the table view has left editing mode.
上面的兩個(gè)方法并沒怎么執(zhí)行…
http://blog.wangluyuan.cc/2017/11/18/iOS-%E4%B8%BATableView%E5%B7%A6%E6%BB%91%E5%88%A0%E9%99%A4%E6%B7%BB%E5%8A%A0%E5%9B%BE%E7%89%87/
上面的鏈接表示 在修改右側(cè)滑動(dòng)的按鈕設(shè)置圖片的時(shí)候可以用到這兩個(gè)方法
3.1.31
optional func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath
按意思 就是例如移動(dòng)cell的時(shí)候 之前是從(1,0)->(2,0)在這個(gè)方
法中可強(qiáng)制改到 任意位置
3.1.32
optional func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int
Asks the delegate to return the level of indentation for a row in a given section.
Returns the depth of the specified row to show its hierarchical position in the section.
q:半天沒有效果
a:發(fā)現(xiàn)禽作,該方法只針對默認(rèn)的UITableViewCell有效喜庞,自定義UITableViewCell是無效的,因?yàn)橄到y(tǒng)并不知道需要縮進(jìn)哪些Cell呐能,解決方法是在自定義UITableViewCell類中重寫 layoutSubviews方法:
https://lazybubble.xyz/cai-keng-zhi-zi-ding-yi-uitableviewcellde-suo-jin-pageworkkai-fa/
3.1.33
optional func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -> Bool
Asks the delegate if the editing menu should be shown for a certain row.
If the user tap-holds a certain row in the table view, this method (if implemented) is invoked first. Return false if the editing menu shouldn’t be shown—for example, the cell corresponding to the row contains content that shouldn’t be copied or pasted over.
true if the editing menu should be shown positioned near the row and pointing to it, otherwise false. The default value is false.
tableView:shouldShowMenuForRowAt方法必須返回 true辈毯,才能長按顯示文本菜單械荷。tableView:canPerformAction:forRowAt方法,讓文本菜單只顯示 copy(復(fù)制)一個(gè)選項(xiàng)版仔。tableView:performAction:forRowAt:withSender方法將選中的文本復(fù)制到 pasteBoard 變量中游盲。
3.1.34
optional func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool
Asks the delegate if the editing menu should omit the Copy or Paste command for a given row.
//上面兩個(gè)方法主要用于點(diǎn)擊cell的時(shí)候長按給一個(gè)menu
3.1.35 iOS 9.0
optional func tableView(_ tableView: UITableView, canFocusRowAt indexPath: IndexPath) -> Bool
Summary
Asks the delegate whether the cell at the specified index path is itself focusable.
3.1.36
optional func tableView(_ tableView: UITableView, shouldUpdateFocusIn context: UITableViewFocusUpdateContext) -> Bool
Summary
Asks the delegate whether the focus update specified by the context is allowed to occur
3.1.37
optional func tableView(_ tableView: UITableView, didUpdateFocusIn context: UITableViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator)
Summary
Tells the delegate that a focus update specified by the context has just occurred.
3.1.38
optional func indexPathForPreferredFocusedView(in tableView: UITableView) -> IndexPath?
Summary
Asks the delegate for the table view’s index path for the preferred focused view.
//Focus 焦點(diǎn) 這個(gè)是新的代理方法 ios9之后
canFocusRowAt
shouldUpdateFocusIn
didUpdateFocusIn
indexPathForPreferredFocusedView
以上四個(gè)方法暫不研究了
3.1.39
optional func tableView(_ tableView: UITableView, shouldSpringLoadRowAt indexPath: IndexPath, with context: UISpringLoadedInteractionContext) -> Bool
Override this method when you want to selectively disable spring-loaded interactions with the rows of your table. For example, you might return false for rows that represent leaf content and not a folder of content. If you do not implement this method, the table view performs spring-loading animations on the row when it is not currently being dragged.By default, spring-loading animations are performed on the entire row. To modify these animations, modify the provided context object. For example, you might use the context object to apply the spring-loading animations to a single subview of the row instead of to the entire row.