It's lifetime mission for iOS developers to optimize the use of UITableView. Fortunately, I managed a declarative way to use it inspired by Arkadiusz Holko's Article.
This approach allows crafting a tableView with different kind of cells much easier and faster.
Here is how you initialize a full feature UITableView
import DDTableViewController
let cellConfigurators:[Array<DDCellConfiguratorType>] = [
// section 0
[
// section 0 row 0
DDCellConfigurator<ImageCell>(viewData: ImageCellViewData(image: UIImage(named: "sample.png")!), initFromNib: false),
// section 0 row 1
DDCellConfigurator<TextCell>(viewData: TextCellViewData(text: "Hello World"), initFromNib: false)
],
//section 1
[
DDCellConfigurator<ImageCell>(viewData: ImageCellViewData(image: UIImage(named: "sample2.png")!), initFromNib: false)
]
// ...
]
let tableVC = DDTableViewController(cellConfigurators: cellConfigurators)
Adopt the protocol Updatable
for all your UITableViewCell
subclasses:
class CustomCell:UITableViewCell{
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
...
}
...
}
struct CustomCellViewData {
// Declare all properties you need to decorate the cell
var image:UIImage
}
extension CustomCell: Updatable {
typealias ViewData = CustomCellViewData
func updateWithViewData(viewData: ViewData) {
// Decorate your cell with the viewData
}
static func heightWithViewData(viewData: ViewData) -> CGFloat {
return 60
}
}
use_frameworks!
pod 'DDTableViewController'
git "wddwycc/DDTableViewController" "master"
Drop files in Source
folder into your project.
func insertCellAtIndexPath(indexPath indexPath:NSIndexPath, withCellConfigurator cellConfigurator:CellConfiguratorType, RowAnimation animation:UITableViewRowAnimation)
func deleteCellAtIndexPath(indexPath indexPath:NSIndexPath, withRowAnimation animation:UITableViewRowAnimation)
func insertCellAtTopWith(cellConfigurator:DDCellConfiguratorType, RowAnimation animation:UITableViewRowAnimation) {
func insertCellAtBottomWith(cellConfigurator:DDCellConfiguratorType, RowAnimation animation:UITableViewRowAnimation) {
// Manually manipulate the model layer
tableVC.cellConfigurators.append(...)
tableVC.tableView.reloadData()
func scrollToBottom(animated animated:Bool)
func scrollToTop(animated animated:Bool)
I recommend to use Kingfisher to Simplify Cell Logic
func updateWithViewData(viewData: ViewData) {
...
imageView.kf_setImageWithURL(NSURL(string: viewData.imageURL)!,
placeholderImage: nil,
optionsInfo: nil,
progressBlock: { (receivedSize, totalSize) -> () in
print("Download Progress: \(receivedSize)/\(totalSize)")
},
completionHandler: { (image, error, cacheType, imageURL) -> () in
print("Downloaded and set!")
}
)
}
// when cell disappear, cancel the download task and later presentation.
override func prepareForReuse() {
super.prepareForReuse()
imageView.kf_cancelDownloadTask()
}