iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 21
1
自我挑戰組

Hey! UIKit, 做個朋友吧~系列 第 21

Day 21: 來自深淵-UITableView(VI)

今天來談談一些table相關的參數取得,以及cell相關的操作。

Getting Numbers

table view透過numberOfRows(inSection:)及numberOfSections從data source裡取得row與section的值。
如果直接定義numberOfRows(inSection:)的話,會產生編程上的錯誤。不過class繼承data source時本來就會強迫定義tableView(_:numberOfRowsInSection:)了,應該沒有人會無聊到再定義一次numberOfRows(inSection:)吧!

Getting Cell / Section-Based View

Cell For Row

table view透過cellForRow(at:)給定一個IndexPath從data source取得特定row所參照的cell。
此function回傳的值是optional UITableViewCell,如果回傳值為nil代表此row的cell是不可視的(沒有cell格式)或是index out of range。

Header/Footer View Of Section

table view透過headerView(forSection:)及footerView(forSection:)給定一個section值取得相對應的section-based的header view和footer view(非table view的header/footer view)。
此function回傳了一個optional UITableViewHeaderFooterView,如果回傳值為nil代表此section沒有header/footer view。

IndexPath

table view透過indexPath(for:)給定一個UITableViewCell取得參照這個cell的row與section的indexPath。如果回傳值為nil代表該indexPath無效。

透過indexPathForRow(at:)給定一個點座標,取得該點座標位置在table上相對應的row與section的indexPath。如果回傳值為nil代表該點座標於table中沒有任何的row可參照。

而相似於上面的function,table view透過indexPathsForRows(in:)給定一個座標範圍,取得該座標範圍在table上包含的row與section的indexPath所組成的陣列。如果回傳值為nil,代表該座標範圍內不存在任何的row。

Visible Cells/Rows

table view透過visibleCells取得目前table中可見的UITableViewCell所組成的陣列。而透過indexPathsForVisibleRows取得可見的row的IndexPath的所組成的陣列,這2個properties都是get-only。
其中[IndexPath]是optional,如果indexPathsForVisibleRows的值為nil,代表沒有row是可視的。

Selecting Row

IndexPath For Row

與前面提到的visible cell相似,都是get-only的propreties。
透過indexPathForSelectedRow取得被選取的row與section的indexPath。如果取得的值為nil代表此indexPath無效,如果同時有多個row被選取,則只會顯示第一個被選取的indexPath以及最低索引值的section與row。
而table view透過indexPathsForSelectedRows取得被選取的row與section們的indexPath所組成的陣列。如果取得的值為nil,代表沒有任何的rows被選取。

Allow

table view用allowsSelection指定一個布林值,來決定rows能不能被使用者所選取,預設值為true,也就是使用者可選取表格列。如果table當下的狀態為isEditing,則此property不會被執行。

而allowsMultipleSelection決定了rows能不能被多重選取,預設值為false。如果此值為true,則在非isEditing的狀態下只要row被點擊就會切換為選取狀態,而再點擊會取消選取狀態。

剛剛一直提到非isEditing狀態,就是為了幫接下來的這個property鋪梗,allowsSelectionDuringEditing如果為true,則rows在isEditing的狀態下也會被選取,預設值為false。

而allowsMultipleSelectionDuringEditing就是允許在isEditing狀態下多重選取。當此property的值為true的時後,進入isEditing的狀態下rows旁邊就會出現checkmark。大家應該都有在編輯照片時看過這個功能,應該是再熟悉不過了!

而這個property通常與indexPathsForSelectedRows搭配使用,取出被選取的rows資料再進行後續動作。

Inserting / Deleting / Moving

Inserting / Deleting Row And Section

table view使用insertRows(at:with:)及deleteRows(at:with:)指定一個indexPath,明確告訴row插入及刪除的位置(section & row),並搭配一個RowAnimation。
另外使用insertSections(:with:)及deleteSections(:with:)給定section的index,依此input進行插入及刪除的動作,並搭配一個RowAnimation。

RowAnimation是個enum,有automatic、bottom、fade、left、middle、none、right、top,會於row/section插入與刪除時有不同的呈現。例如right是從row的底部插入/消失,而fade就有點像淡入淡出的特效。

如果在beginUpdate()-endUpdate()中調用inseting和deleting的方法的話,不管inserting和deleting調用的順序如何,table view都會在執行完全部的deleting動作後才會進行inserting。

Move Row / Section

table view使用moveRow(at:to:)移動row到新的位置,呼叫一次function只能移動一個row;另外使用moveSection(_:toSection:)移動一整個區塊的section到新的位置:

@objc func moveSectionAction(_ sender: UIButton) {
    newTableView.moveSection(0, toSection: 2)
}

moving不像inserting和deleting有動畫相關的參數。當moving的動作被呼叫時,row/section會從起始位置直線移動到最終的位置。所以如果想要結合moving與inserting/deleting在同一個動畫中完成的話,可以將這些method寫在beginUpdate()-endUpdate()的區塊當中。

另外剛剛有提到,moveRow(at:to:)每次呼叫只能移動一個row,所以如果想要一次移動多個row的話,也可以把多個moveRow(at:to:)的function寫在beginUpdate()-endUpdate()的區塊當中便可以完成。

關於beginUpdate()-endUpdate()的function將會在明天提到。
敬請期待。


上一篇
Day 20: 來自深淵-UITableView(V)
下一篇
Day 22: 來自深淵-UITableView(VII)
系列文
Hey! UIKit, 做個朋友吧~30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言