天天看點

Swift - 在TableViewCell中擷取父TableView(附:擷取任意類型的父View)

一、在TableViewCell裡擷取對應的TableView

有時我們需要在自定義的單元格( tableViewCell )中擷取其所在的表格( tableView )對象。除了可以從外部把  tableView  傳入到  cell  中去外,還可以通過循環周遊  cell  的  superview  來得到其所在的父  tableView 。

1,擴充UITableViewCell

為友善使用,這裡對  UITableViewCell  進行擴充,添加個方法用來擷取其所在的  tableView 。

1 2 3 4 5 6 7 8 9 10 11

extension 

UITableViewCell

{

//傳回cell所在的UITableView

func

superTableView() -> 

UITableView

? {

for

view 

in

sequence(first: 

self

.superview, next: { $0?.superview }) {

if

let

tableView = view 

as

UITableView

{

return

tableView

}

}

return

nil

}

}

2,使用樣例

我們在每個單元格尾部添加一個按鈕,點選後列印出這個按鈕所在單元格的  indexPath。(先得到  tableView,再根據  tableView 擷取到目前  cell 所在的  indexPath ) (1)效果圖     

Swift - 在TableViewCell中擷取父TableView(附:擷取任意類型的父View)
Swift - 在TableViewCell中擷取父TableView(附:擷取任意類型的父View)

(2)樣例代碼

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

import

UIKit

class

ViewController

UIViewController

UITableViewDelegate

UITableViewDataSource

{

var

tableView:

UITableView

?

override

func

loadView() {

super

.loadView()

}

override

func

viewDidLoad() {

super

.viewDidLoad()

//建立表視圖

self

.tableView = 

UITableView

(frame: 

self

.view.frame, style:.plain)

self

.tableView!.delegate = 

self

self

.tableView!.dataSource = 

self

self

.tableView!.allowsSelection = 

false

//建立一個重用的單元格

self

.tableView!.register(

MyTableCell

.

self

, forCellReuseIdentifier: 

"tableCell"

)

self

.view.addSubview(

self

.tableView!)

}

//在本例中,隻有一個分區

func

numberOfSections(

in

tableView: 

UITableView

) -> 

Int

{

return

1

}

//傳回表格行數(也就是傳回控件數)

func

tableView(_ tableView: 

UITableView

, numberOfRowsInSection section: 

Int

) -> 

Int

{

return

20

}

//建立各單元顯示内容(建立參數indexPath指定的單元)

func

tableView(_ tableView: 

UITableView

, cellForRowAt indexPath: 

IndexPath

)

-> 

UITableViewCell

{

//建立一個重用的單元格

let

cell = tableView

.dequeueReusableCell(withIdentifier: 

"tableCell"

for

: indexPath)

as

MyTableCell

cell.textLabel?.text = 

"條目\(indexPath.row)"

return

cell

}

override

func

didReceiveMemoryWarning() {

super

.didReceiveMemoryWarning()

}

}

//單元格類

class

MyTableCell

UITableViewCell

{

var

button:

UIButton

!

//初始化

override

init

(style: 

UITableViewCellStyle

, reuseIdentifier: 

String

?) {

super

.

init

(style: style, reuseIdentifier: reuseIdentifier)

button = 

UIButton

(frame:

CGRect

(x:0, y:0, width:40, height:25))

button.setTitle(

"點選"

for

:.normal) 

//普通狀态下的文字

button.backgroundColor = 

UIColor

.orange

button.layer.cornerRadius = 5

button.titleLabel?.font = 

UIFont

.systemFont(ofSize: 13)

//按鈕點選

button.addTarget(

self

, action:#selector(tapped(_:)), 

for

:.touchUpInside)

self

.addSubview(button)

}

//布局

override

func

layoutSubviews() {

super

.layoutSubviews()

button.center = 

CGPoint

(x: bounds.size.width - 35, y: bounds.midY)

}

//按鈕點選事件響應

func

tapped(_ button:

UIButton

){

let

tableView = superTableView()

let

indexPath = tableView?.indexPath(

for

self

)

print

(

"indexPath:\(indexPath!)"

)

}

required

init

?(coder aDecoder: 

NSCoder

) {

fatalError(

"init(coder:) has not been implemented"

)

}

}

二、擷取任意類型的父View 

我們可以對上面的方法做個改進,通過擴充  UIView,讓我們可以獲得任意視圖對象( View)所在的指定類型的父視圖。

1,擴充View

這裡對  UIView 進行擴充,根據傳入的類型,循環周遊擷取該類型的父  View。

1 2 3 4 5 6 7 8 9 10 11

extension 

UIView

{

//傳回該view所在的父view

func

superView<

T

UIView

>(of: 

T

.

Type

) -> 

T

? {

for

view 

in

sequence(first: 

self

.superview, next: { $0?.superview }) {

if

let

father = view 

as

T

{

return

father

}

}

return

nil

}

}

2,使用樣例

這裡對上面樣例代碼做個修改,之前我們在單元格中這麼得到該  cell 所在的  tableView:

1

let

tableView = superTableView()

現在改成這樣:

1

let

tableView = superView(of: 

UITableView

.

self

)