保持ViewControllers的精简并使用MVVMC帮助我保持这么简单。 Obj.io有一个非常好的教程site。不幸的是,本教程仅在Objective-C中。
我正在尝试切换到Swift,并且非常迅速地移动,直到我到达用于配置单元格的块。
在教程中,他们创建了一个块typedef
:
typedef void (^TableViewCellConfigureBlock)(id cell, id item);
在创建单元格时返回cellForRowAtIndexPath
中的单元格。
以下是一些代码,这是整个项目:Project
void (^configureCell)(PhotoCell*, Photo*) = ^(PhotoCell* cell, Photo* photo) {
cell.label.text = photo.name;
};
photosArrayDataSource = [[ArrayDataSource alloc] initWithItems:photos
cellIdentifier:PhotoCellIdentifier
configureCellBlock:configureCell];
self.tableView.dataSource = photosArrayDataSource;
cellForRowAtIndexPath
:
- (UITableViewCell*)tableView:(UITableView*)tableView
cellForRowAtIndexPath:(NSIndexPath*)indexPath {
id cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier
forIndexPath:indexPath];
id item = [self itemAtIndexPath:indexPath];
configureCellBlock(cell,item);
return cell;
}
问题:如何在Swift 1.2+中完成相同的操作?我应该使用closure
,protocol delegate
等吗?更重要的是,我如何在cellForRowAtIndexPath
中调用它?
我是Swift的新手,因此非常感谢解决方案代码。谢谢。
答案 0 :(得分:4)
您可以在此处使用swift closures
。将closureType定义为,
typealias TableViewCellConfigureBlock = (cell : AnyObject , item : AnyObject) -> Void
然后定义closure
喜欢,
let configureCellBlock : TableViewCellConfigureBlock = { (cell : PhotoCell, photo : Photo) in
cell.label.text = photo.name
} as TableViewCellConfigureBlock
然后在cellForRowAtIndexPath:
中,您可以像以前一样使用它,
configureCellBlock(cell: yourCell, item: yourPhotoItem)
答案 1 :(得分:1)
闭包是您使用的而不是块。您可以像在Objective-C中一样在Swift中实现协议。必须从NSObject继承以符合此协议。泛型在这里会很好,但是从Swift 1.2开始,它们不能用于与Objective-C的互操作。
class ArrayDataSource : NSObject, UITableViewDataSource {
let array: [AnyObject]
let identifier: String
let configureCell: (UITableViewCell, AnyObject) -> ()
init(array: [AnyObject], identifier: String, configureCell: (UITableViewCell, AnyObject) -> ()) {
self.array = array
self.identifier = identifier
self.configureCell = configureCell
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let item: AnyObject = array[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier(identifier) as! UITableViewCell
configureCell(cell, item)
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
}
let tableView = UITableView()
tableView.dataSource = ArrayDataSource(array: ["foo", "bar", "baz"], identifier: "foo", configureCell: { (cell, obj) -> () in
cell.textLabel?.text = "bar"
})
答案 2 :(得分:1)
在 Swift 2.0 中,您可以使用泛型(如此处所示 - sample github repo),这很容易。
但是在 Swift 1.2 中你需要删除泛型(不能使泛型类继承自objc类型)。请改用协议。这样您就不需要传递单元配置闭包并使用协议的强大功能。
你会这样:
protocol CellDescription {
var title: String { get }
var image: UIImage { get }
}
您希望在tableview中显示的模型需要实现协议
class Question: CellDescription {
var image: Image {
return UIImage(named: "whatever")!
}
var title: String {
return "cell title"
}
}
然后,您可以UITableViewController
使用属性items: [CellDescription]
,并按照以下方式创建:
class CustomTableViewController: UITableViewController {
var items: [CellDescription] = []
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(pickerCell, forIndexPath: indexPath)
cell.textLabel?.text = items[indexPath.item].title
cell.imageView?.image = items[indexPath.item].image
return cell
}
}