Created
April 25, 2016 02:22
-
-
Save tianskylan/ba9eea908cd6e71fae79190948f7c590 to your computer and use it in GitHub Desktop.
An attempt of UICollectionViewCell Decoration and Configuration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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