下面是游乐场代码。
我的问题是针对以下一行:
let recentItemsVC = ItemsViewController(items: recentItems, cellDescriptor: {$0.cellDescriptor })
我知道ItemsViewController
对cellDescriptor
采取了封闭措施,但是我无法绕过{$0.cellDescriptor}
本身的含义。此处没有filter
,map
,compactMap
,filter
等名称。
两个问题:
1。游乐场表演(4次)。是什么意思?
2。通过{ $0.cellDescriptor }
本身是什么意思?
代码:
import UIKit
import PlaygroundSupport
struct Album {
var title: String
}
struct Artist {
var name: String
}
struct CellDescriptor {
let cellClass: UITableViewCell.Type
let reuseIdentifier: String
let configure: (UITableViewCell) -> ()
init<Cell: UITableViewCell>(reuseIdentifier: String, configure: @escaping (Cell) -> ()) {
self.cellClass = Cell.self
self.reuseIdentifier = reuseIdentifier
self.configure = { cell in
configure(cell as! Cell)
}
}
}
final class ItemsViewController<Item>: UITableViewController {
var items: [Item] = []
let cellDescriptor: (Item) -> CellDescriptor
var didSelect: (Item) -> () = { _ in }
var reuseIdentifiers: Set<String> = []
init(items: [Item], cellDescriptor: @escaping (Item) -> CellDescriptor) {
self.cellDescriptor = cellDescriptor
super.init(style: .plain)
self.items = items
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = items[indexPath.row]
didSelect(item)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = items[indexPath.row]
let descriptor = cellDescriptor(item)
if !reuseIdentifiers.contains(descriptor.reuseIdentifier) {
tableView.register(descriptor.cellClass, forCellReuseIdentifier: descriptor.reuseIdentifier)
reuseIdentifiers.insert(descriptor.reuseIdentifier)
}
let cell = tableView.dequeueReusableCell(withIdentifier: descriptor.reuseIdentifier, for: indexPath)
descriptor.configure(cell)
return cell
}
}
final class ArtistCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .value1, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
final class AlbumCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .value2, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
let artists: [Artist] = [
Artist(name: "Prince"),
Artist(name: "Glen Hansard"),
Artist(name: "I Am Oak")
]
let albums: [Album] = [
Album(title: "Blue Lines"),
Album(title: "Oasem"),
Album(title: "Bon Iver")
]
enum RecentItem {
case artist(Artist)
case album(Album)
}
let recentItems: [RecentItem] = [
.artist(artists[0]),
.artist(artists[1]),
.album(albums[1])
]
extension Artist {
func configureCell(_ cell: ArtistCell) {
cell.textLabel?.text = name
}
}
extension Album {
func configureCell(_ cell: AlbumCell) {
cell.textLabel?.text = title
}
}
extension RecentItem {
var cellDescriptor: CellDescriptor {
switch self {
case .artist(let artist):
return CellDescriptor(reuseIdentifier: "artist", configure: artist.configureCell)
case .album(let album):
return CellDescriptor(reuseIdentifier: "album", configure: album.configureCell)
}
}
}
let recentItemsVC = ItemsViewController(items: recentItems, cellDescriptor: {$0.cellDescriptor })
let nc = UINavigationController(rootViewController: recentItemsVC)
nc.view.frame = CGRect(x: 0, y: 0, width: 200, height: 300)
PlaygroundPage.current.liveView = nc.view
答案 0 :(得分:1)
那是代码行:
init(items: [Item], cellDescriptor: @escaping (Item) -> CellDescriptor) {
您使用ItemsViewController
数组和回调方法初始化Item
。回调方法接受Item
作为参数。并且Item
有一个名为cellDescriptor
答案 1 :(得分:1)
recentItems
+1的计数 {$0.cellDescriptor}
是一个闭包。其签名为@escaping (Item) -> CellDescriptor
。这意味着它采用通用类型Item
并返回CellDescriptor
。在这种情况下,对于recentItems
的每个元素,它将返回该元素的cellDescriptor
。无论是艺术家还是专辑,cellDescriptor
都由以下部分代码定义:
扩展名最近项{ var cellDescriptor:CellDescriptor { 切换自我{ 案例。艺术家(艺术家): 返回CellDescriptor(reuseIdentifier:“ artist”,配置:artist.configureCell) 案例。专辑(让相册): 返回CellDescriptor(reuseIdentifier:“ album”,配置:album.configureCell) } } }
设置reuseIdentifier
并通过将textLabel?.text
设置为艺术家的名字或专辑的标题来配置单元格。