利用 insetGrouped 實現表格 section 的內縮圓角背景

在 iOS App 上,我們時常看到下圖的設計,表格的 Section 有著內縮的圓角背景。

左邊是 Settings App,右邊是 Health App

要怎麼讓 Section 有內縮圓角背景呢?很簡單,利用 iOS 13 的 table view style insetGrouped 即可快速實現此效果。

定義資料型別

我們將以獨步文化好看的推理小說為例,以下先定義資料型別 Book。

struct Book {
let name: String
let author: String
}

實現表格 section 的內縮圓角背景

從 storyboard 設計畫面

在 storyboard 加入 table view controller,將 class 設為繼承 UITableViewController 的 BookTableViewController,將 table view 的 style 設為 Inset Grouped

ps: 若是從程式產生 BookTableViewController,可用 BookTableViewController(style: .insetGrouped),在產生 controller 時指定 style。

將 cell 的 Style 設為 Subtitle,Identifier 設為 BookCell。

產生表格顯示的推理小說

我們希望表格顯示兩個 section,第一個 section 顯示東野圭吾的小說,第二個 section 顯示伊坂幸太郎的小說。我們將表格顯示的推理小說存在 booksDic,從 booksDic["東野圭吾"] 可得到東野圭吾小說的 array,從 booksDic["伊坂幸太郎"] 可得到伊坂幸太郎小說的 array。

class BookTableViewController: UITableViewController {

var booksDic = [String: [Book]]()

override func viewDidLoad() {
super.viewDidLoad()
createBooks()
}

func createBooks() {
let books = [
Book(name: "嫌疑犯X的獻身", author: "東野圭吾"),
Book(name: "白夜行", author: "東野圭吾"),
Book(name: "Fish Story", author: "伊坂幸太郎"),
Book(name: "重力小丑", author: "伊坂幸太郎")
]
booksDic = Dictionary(grouping: books, by: { book in
book.author
})
}

設定表格顯示的內容,定義 UITableViewDataSource 的相關 function

第一個 section 顯示東野圭吾的小說,第二個 section 顯示伊坂幸太郎的小說。

override func numberOfSections(in tableView: UITableView) -> Int {
return booksDic.count
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return booksDic["東野圭吾"]?.count ?? 0
} else {
return booksDic["伊坂幸太郎"]?.count ?? 0
}
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "BookCell", for: indexPath)
let book: Book
if indexPath.section == 0 {
book = booksDic["東野圭吾"]![indexPath.row]
} else {
book = booksDic["伊坂幸太郎"]![indexPath.row]
}
var content = cell.defaultContentConfiguration()
content.text = book.name
content.secondaryText = book.author
content.image = UIImage(named: book.name)
content.imageProperties.maximumSize = CGSize(width: 100, height: 100)
cell.contentConfiguration = content
return cell
}

設定 cell 時,我們採用 iOS 14 推出的 UIListContentConfiguration,相關說明可參考以下連結。

結果

如下圖所示,格表的 section 出現了內縮圓角背景,只是它在 dark mode 比較明顯,在非 dark mode 由於 cell & table 都是白的,所以看不出內縮圓角。

設定表格的背景顏色

我們可以設定 table view 的背景顏色,比方褐色,突顯 cell 白色時 section 的內縮圓角。

設定 Section 的背景顏色

設定 cell 的背景顏色即可控制 Section 的背景顏色,比方將 cell 的 Background 設為粉紅色。

設定分隔線內縮的寬度

我們也可以設定分隔線內縮的寬度,從 table view 的 Separator Inset 選擇 Custom,然後設定 Left & Right 內縮的寬度。

調整 section 內縮的寬度

想調整 section 內縮的寬度,目前並沒有可設定的屬性或 function,因此我們只能在 view controller 另外加入 table view,然後調整 table view 的寬度實現想要的內縮長度。

ps: 若是從程式產生 table view,可用 UITableView(frame: .zero, style: .insetGrouped),在產生 table view 時指定 style。

比方我們覺得預設的內縮寬度太長了,想要它短一點。此時我們可將 table view 的寬度設大一點。如下圖所示,透過紅色框框設定的條件,table view 的寬度將比整個螢幕的寬度還長,左右各超出 10 points。

當 table view 變寬時,cell 的寬度也跟著變寬,因此如下圖所示,我們將感覺 section 內縮的寬度縮小了。

每個 cell 都有內縮的圓角背景

剛剛的例子是整個 section 有著內縮的圓角背景,我們也可以讓每個 cell 都有內縮的圓角背景。

怎麼做呢? 很簡單,讓一個 section 只有一個 cell,section 的數量等於資料的數量,此時每個 cell 都會有著 insetGrouped 造成的內縮圓角背景。

class BookTableViewController: UITableViewController {
let books = [
Book(name: "嫌疑犯X的獻身", author: "東野圭吾"),
Book(name: "白夜行", author: "東野圭吾"),
Book(name: "Fish Story", author: "伊坂幸太郎"),
Book(name: "重力小丑", author: "伊坂幸太郎")
]

override func viewDidLoad() {
super.viewDidLoad()
}

override func numberOfSections(in tableView: UITableView) -> Int {
return books.count
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "BookCell", for: indexPath)
let book = books[indexPath.section]
var content = cell.defaultContentConfiguration()
content.text = book.name
content.secondaryText = book.author
content.image = UIImage(named: book.name)
content.imageProperties.maximumSize = CGSize(width: 100, height: 100)
cell.contentConfiguration = content
return cell
}
}

collection view section 的內縮圓角背景

collection view 的 section 也可以有內縮圓角背景,透過 iOS 13 的 UICollectionViewCompositionalLayout & NSCollectionLayoutDecorationItem 實現。

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com