實現 UITableViewCell 側滑操做列表

曾經

咱們都知道 UITableView 支持實現側滑操做,通常用來實現刪除一個項目,實現起來也很簡單,只須要實現 UITableView 的三個代理方法swift

  • 首先告訴UITableView咱們須要實現的操做類型,好比返回一個.delete
public func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
	return .delete
}
複製代碼
  • 而後告訴 UITableView 側滑時刪除按鈕上顯示的文字
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

更況且還有一件更坑的事情:editingStyleForRowtitleForDeleteConfirmationButton這兩個方法屬於UITableViewDelegate協議,而commit editingStyle這個方法屬於UITableViewDataSource協議。數組

這意味着,若是你爲UITableView實現了通用的DataSource協議,那麼要實現側滑操做就不可避免要破壞代碼結構了。。。閉包

另外,側滑支持多項操做的需求愈來愈旺盛,而此時咱們的經典三部曲已經沒法勝任工做了。spa

這時候要麼選擇第三方的實現方案,作好隨時被坑的準備;要麼,本身去實現一個更大的。。。坑?設計

iOS 8 以後

估計蘋果的工程師也爲本身這個天才的設計折服了吧,因而在 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?
}
複製代碼

先來看構造器,便利構造器接受三個屬性:styletitlehandlercode

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,運行以後能夠發現,defaultdestructive默認都是紅色,normal默認是灰色。這裏只是簡單定義了一個alertTitle方法用來響應點擊反饋,實際項目中須要替換成特定的業務邏輯。

###結語 至此終於水完了UITableViewRowAction相關的內容,雖然這是個 iOS 8 就出來的特性了,不過最近才被我注意到,並且尚未把backgroundEffect屬性的特性摸清,實在是慚愧。

好消息是如今大多數 App 都是至少支持 iOS 8 + 了吧?能夠不再用寫繁瑣的三部曲了。

相關文章
相關標籤/搜索