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会根据tableView的滚动 然后悬浮在最上层
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.)
(默认都为true,但是如果为false 的行 就是 删除 插入都不会再有动画 ,UITableViewCell.EditingStyle.none这个当然也可以)
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
(点击右边的 跳到第几个.)
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.
(左滑,点击删除 插入 等等操作的时候 你怎么干 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
(应该是其他的代理方法设置了 才在这边可以执行)
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.
)
理解错误了
what's the different between “cellForRowAtIndexPath” and “willDisplayCell: forRowAtIndexPath:”
1.两者所处的代理方法不同,且一个必须执行,一个是可选执行
- willDisplayCell 在 cellForRowAtIndexPath之后执行 是最后调整UI的机会, 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下进行.因为 cellForRow 中 直接会把20张加载好 会有大量的实例请求.在 willDisplayCell 中 用户可以看到哪实例请求到哪 所以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.
还有一种是播放视频或者图片的时候 在cell中 可以节省流量
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:还不知道在哪执行这个方法
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.
点中某一行的时候允不允许他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;
点的是哪个 返回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.
以上的执行
顺序
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 会执行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 但是没有任何反应
a:需要在tableView.isEditing 为true 的情况下才能使用
补充:
系统的
delete样式 ,点击会右边划出删除按钮
insert 样式,点击会执行 commit editingStyle方法
若是 UITableViewCellEditingStyle.init(rawValue: 3) 系统无法区分,点击无效果
如果想实现的话 还是自定义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.
你想自定义侧滑的时候的custom actions 就执行这个方法
自定义 并且执行方法
补充:
UITableViewRowAction
初始化方法 颜色 文字 都是可以调的
还有一个属性
@NSCopying open var backgroundEffect: UIVisualEffect?
….
不知道干啥的
3.1.26 iOS 11
optional func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
左侧滑动自定义按钮
3.1.27 iOS 11
optional func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
右侧滑动自定义按钮
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 即可,表示关闭缩进。
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.
上面的两个方法并没怎么执行…
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/
上面的链接表示 在修改右侧滑动的按钮设置图片的时候可以用到这两个方法
3.1.31
optional func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath
按意思 就是例如移动cell的时候 之前是从(1,0)->(2,0)在这个方
法中可强制改到 任意位置
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:发现,该方法只针对默认的UITableViewCell有效,自定义UITableViewCell是无效的,因为系统并不知道需要缩进哪些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(复制)一个选项。tableView:performAction:forRowAt:withSender方法将选中的文本复制到 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.
//上面两个方法主要用于点击cell的时候长按给一个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 焦点 这个是新的代理方法 ios9之后
canFocusRowAt
shouldUpdateFocusIn
didUpdateFocusIn
indexPathForPreferredFocusedView
以上四个方法暂不研究了
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.