Skip to content

Instantly share code, notes, and snippets.

@tianskylan
Created April 25, 2016 02:22
Show Gist options
  • Save tianskylan/ba9eea908cd6e71fae79190948f7c590 to your computer and use it in GitHub Desktop.
Save tianskylan/ba9eea908cd6e71fae79190948f7c590 to your computer and use it in GitHub Desktop.
An attempt of UICollectionViewCell Decoration and Configuration
import Foundation
import UIKit
// MARK: - Decorator and Configurator protocols
protocol Decorator {
associatedtype Decoratable
init(dependencyManager: VDependencyManager)
func decorate(cell: Decoratable)
}
protocol Configurator {
associatedtype CellData
associatedtype Configuratable
func configure(cell: Configuratable, with: CellData)
}
// MARK: - Concrete implementations
struct HashtagCellDecorator: Decorator {
let dependencyManager: VDependencyManager
init(dependencyManager: VDependencyManager) {
self.dependencyManager = dependencyManager
}
func decorate(cell: HashtagCell) {
cell.titleLabel.font = dependencyManager.fontForKey()
}
}
struct HashtagCellConfigurator: Configurator {
func configure(cell: HashtagCell, with hashtag: Hashtag) {
cell.titleLabel.text = hashtag.tag
}
}
// MARK: - Data Source and Cell
class HashtagCollectionViewDataSource {
var collectionView: UICollectionView?
var dependencyManager: VDependencyManager!
var hashtagDecorator: HashtagCellDecorator {
return HashtagCellDecorator(dependencyManager: dependencyManager)
}
let hashtagConfigurator = HashtagCellConfigurator()
func cellForItemAtIndex() {
let cell = collectionView?.dequeueReusableCellWithReuseIdentifier("", forIndexPath: NSIndexPath(forItem: 0, inSection: 0)) as! HashtagCell
hashtagDecorator.decorate(cell)
hashtagConfigurator.configure(cell, with: Hashtag())
}
}
class HashtagCell: UICollectionViewCell {
@IBOutlet private(set) var titleLabel: UILabel!
}
/*
Pros:
1. Views are dumb - just holds the Outlets
2. Controllers are thin - just a middleman passing data around
3. Separate of concerns: If we want to decorate the same cell differently (5.0 vs 4.0, experiments, etc..) -> Make a new Decorator
4. Unified way for cell decoration and configuration
5. Concrete Decorator and Configurators have the freedom to define what they can do
6. We could expand this to custom views in general
Cons:
1. cells need to expose their IBOutlets as `private(set) var`
2. Some extra work to do for simple cells
3. How can we prevent decorating the cells multiple times?
*/
// MARK: - Models for testing
struct Hashtag {
let tag = "test tag name"
}
struct VDependencyManager {
func fontForKey() -> UIFont {
return UIFont()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment