咱們都知道 UITableView
支持實現側滑操做,通常用來實現刪除一個項目,實現起來也很簡單,只須要實現 UITableView
的三個代理方法swift
UITableView
咱們須要實現的操做類型,好比返回一個.delete
public func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .delete
}
複製代碼
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "Delete"
}
複製代碼
public func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
// Do somthing
}
複製代碼
幾個項目下來,咱們對這個三部曲早就是倒背如流了。不過有時候會想,一個簡單的操做按鈕,須要實現三個 Delegate 方法來達到效果,會不會太繁瑣了。。。api
更況且還有一件更坑的事情:editingStyleForRow
和titleForDeleteConfirmationButton
這兩個方法屬於UITableViewDelegate
協議,而commit editingStyle
這個方法屬於UITableViewDataSource
協議。數組
這意味着,若是你爲UITableView
實現了通用的DataSource
協議,那麼要實現側滑操做就不可避免要破壞代碼結構了。。。閉包
另外,側滑支持多項操做的需求愈來愈旺盛,而此時咱們的經典三部曲已經沒法勝任工做了。spa
這時候要麼選擇第三方的實現方案,作好隨時被坑的準備;要麼,本身去實現一個更大的。。。坑?設計
估計蘋果的工程師也爲本身這個天才的設計折服了吧,因而在 iOS 8 引入了一個新的 API:UITableViewRowAction
,先來看一看定義壓壓驚:代理
@available(iOS 8.0, *)
open class UITableViewRowAction : NSObject, NSCopying {
public convenience init(style: UITableViewRowActionStyle, title: String?, handler: @escaping (UITableViewRowAction, IndexPath) -> Swift.Void)
open var style: UITableViewRowActionStyle { get }
open var title: String?
@NSCopying open var backgroundColor: UIColor? // default background color is dependent on style
@NSCopying open var backgroundEffect: UIVisualEffect?
}
複製代碼
先來看構造器,便利構造器接受三個屬性:style
、title
、handler
。code
title
這個不用說了,確定就是按鈕顯示的標題了。orm
style
經過定義能夠看到,是一個UITableViewRowActionStyle
類型的枚舉值,經過構造器傳入以後便不可更改了,想來是決定操做按鈕的顯示樣式的吧,destructive
這個單詞是否是很熟悉?事件
@available(iOS 8.0, *)
public enum UITableViewRowActionStyle : Int {
case `default`
case destructive
case normal
}
複製代碼
繼續往下看到handler
,這是一個閉包,顯然是用來響應按鈕點擊事件的了,終於不用另外實現一個Delegate
方法去響應操做事件了麼?自從 iOS 4 以後引入了 block,蘋果已經一發不可收拾了,API 改造大軍正在路上。。。
class 定義裏面還有兩個屬性:
首先看到backgroundColor
,字面意思很好理解,就是背景顏色了,後面註釋了一行小字:default background color is dependent on style。
這證明了咱們的猜測:style
屬性決定了按鈕的樣式,也就是背景顏色,固然,咱們也能夠經過backgroundColor
本身另外指定背景色。
最後一個屬性是backgroundEffect
,是UIVisualEffect
類型的。UIVisualEffect
?!這是啥?有經驗的同窗都知道,這是 iOS 7 以後引入的毛玻璃特效啊,不過研究了半天發現並無卵用😂。也多是我打開的方式不對?有知道的同窗能夠指點下。。。
###實踐 好了,看完了類定義,趕忙來看看怎麼使用吧。先看一下UITableViewDelegate
的定義,關於UITableViewRowAction
只定義了一個方法:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
複製代碼
終於決定拋棄三部曲了麼😳,返回值是個數組,這是支持多個操做項的節奏啊,廢話少說上代碼:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let defaultAction = UITableViewRowAction(style: .default, title: "Default") { (action, indexPath) in
self.alertTitle("Default action at \(indexPath)")
}
let normalAction = UITableViewRowAction(style: .normal, title: "Normal") { (action, indexPath) in
self.alertTitle("Normal action at \(indexPath)")
}
let destructiveAction = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in
self.alertTitle("Delete action at \(indexPath)")
}
return [defaultAction, normalAction, destructiveAction]
}
func alertTitle(_ title: String) {
let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
present(alert, animated: true)
}
複製代碼
這裏定義了三個UITableViewRowAction
,分別對應不一樣的style
,運行以後能夠發現,default
和destructive
默認都是紅色,normal
默認是灰色。這裏只是簡單定義了一個alertTitle
方法用來響應點擊反饋,實際項目中須要替換成特定的業務邏輯。
###結語 至此終於水完了UITableViewRowAction
相關的內容,雖然這是個 iOS 8 就出來的特性了,不過最近才被我注意到,並且尚未把backgroundEffect
屬性的特性摸清,實在是慚愧。
好消息是如今大多數 App 都是至少支持 iOS 8 + 了吧?能夠不再用寫繁瑣的三部曲了。