Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save codetalks-new/210c5f687d2d6db4b138 to your computer and use it in GitHub Desktop.
Save codetalks-new/210c5f687d2d6db4b138 to your computer and use it in GitHub Desktop.
demo for simple Custom UICollectionViewFlowLayout with decoratorView
// Playground - noun: a place where people can play
import UIKit
extension UIColor{
convenience init(hex:Int){
let red = CGFloat((hex >> 16) & 0xff) / 255.0
let green = CGFloat((hex >> 8) & 0xff) / 255.0
let blue = CGFloat( hex & 0xff) / 255.0
self.init(red:red,green:green,blue:blue,alpha:1)
}
}
let textSource = [
"是故意的吗"
,"是我得罪谁了吗"
,"这一天竟然每件事情都失算"
,"只想转个弯"
,"却绕到了飞机场"
,"发现没钱在身上"
,"乌云乌云快走开"
]
func choice<T>(arr:[T]) -> T{
return arr[ random() % arr.count ]
}
func demoTitle() ->String {
return choice(textSource)
}
func demoSummary() -> String{
var maxCount = random() % 5 + 2
var sumary = ""
while maxCount > 0{
sumary += choice(textSource)
maxCount--
}
return sumary
}
class Topic{
var title=""
var summary = ""
init(title:String,summary:String){
self.title = title
self.summary = summary
}
convenience init(){
self.init(title:demoTitle(),summary:demoSummary())
}
}
let redColor = UIColor(hex: 0xda1c5c)
let blueColor = UIColor(hex: 0x117fbb)
let greenColor = UIColor(hex: 0x169f8c)
let colors = [ redColor,blueColor,greenColor ]
let secondaryTextColor = UIColor(hex: 0xb6b6b6)
let backgroundColor = UIColor(hex: 0xefefef)
func primaryColor() -> UIColor{
return colors[ random() % colors.count ]
}
class TopicView:UICollectionViewCell{
let title = UILabel()
let summary = UILabel()
class var identifier:String{
return "TopicView"
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setup(){
contentView.layer.borderWidth = 1
contentView.layer.cornerRadius = 8
contentView.backgroundColor = UIColor.whiteColor()
contentScaleFactor = 2
contentView.contentScaleFactor = 2
title.contentScaleFactor = 2
title.font = UIFont.italicSystemFontOfSize(14)
title.numberOfLines = 1
title.lineBreakMode = .ByTruncatingTail
summary.textColor = secondaryTextColor
summary.font = UIFont.systemFontOfSize(12)
summary.numberOfLines = 2
summary.lineBreakMode = .ByTruncatingTail
contentView.addSubview(title)
contentView.addSubview(summary)
title.setTranslatesAutoresizingMaskIntoConstraints(false)
summary.setTranslatesAutoresizingMaskIntoConstraints(false)
let sbConstraint = NSLayoutConstraint(item: summary, attribute: .Bottom, relatedBy: .Equal, toItem: contentView, attribute: .Bottom, multiplier: 1, constant: -8)
let slConstraint = NSLayoutConstraint(item: summary, attribute: .Leading, relatedBy: .Equal, toItem: contentView, attribute: .Leading, multiplier: 1, constant: 8)
let srConstraint = NSLayoutConstraint(item: summary, attribute:.Trailing , relatedBy: .Equal, toItem: contentView, attribute: .Trailing, multiplier: 1, constant: -8)
let tbConstraint = NSLayoutConstraint(item: title, attribute: .Bottom, relatedBy: .Equal, toItem: summary, attribute: .Top, multiplier: 1, constant: -8)
let tlConstraint = NSLayoutConstraint(item: title, attribute: .Leading, relatedBy: .Equal, toItem: summary, attribute: .Leading, multiplier: 1, constant: 0)
let trConstraint = NSLayoutConstraint(item: title, attribute: .Trailing, relatedBy: .Equal, toItem: contentView, attribute: .Trailing, multiplier: 1, constant: -20)
contentView.addConstraint(sbConstraint)
contentView.addConstraint(slConstraint)
contentView.addConstraint(srConstraint)
contentView.addConstraint(tbConstraint)
contentView.addConstraint(tlConstraint)
contentView.addConstraint(trConstraint)
}
func bind(topic:Topic){
title.text = topic.title
summary.text = topic.summary
let color = primaryColor()
title.textColor = color
contentView.layer.borderColor = color.CGColor
contentView.layoutIfNeeded()
}
}
// debug TopicView
//let topicView = TopicView(frame: CGRect(x: 0, y: 0, width: 240, height: 80))
//topicView.bind(Topic())
class TopicDataSource :NSObject,UICollectionViewDataSource{
var topics:[Topic] = []
override init() {
super.init()
generateDemoData()
}
func generateDemoData(){
var maxCount = random() % 1 + 3
while maxCount > 0 {
topics.append(Topic())
maxCount--
}
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
return topics.count
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell{
let topicView = collectionView.dequeueReusableCellWithReuseIdentifier(TopicView.identifier, forIndexPath: indexPath) as TopicView
topicView.bind(topicAtIndexPath(indexPath))
return topicView
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int{
return 1
}
// MARK: Helper
func topicAtIndexPath(indexPath:NSIndexPath) -> Topic{
return topics[indexPath.item]
}
}
class SeperatorView: UICollectionReusableView {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setup(){
backgroundColor = primaryColor()
}
}
class TopicFlowLayout:UICollectionViewFlowLayout{
struct LayoutKinds {
static let globalHeader = "globalHeader"
static let seperator = "seperator"
}
var seperatorLayoutInfo:[NSIndexPath:UICollectionViewLayoutAttributes] = [:]
override func prepareLayout() {
super.prepareLayout()
registerClass(SeperatorView.classForCoder(), forDecorationViewOfKind: LayoutKinds.seperator)
sectionInset = UIEdgeInsets(top: 36, left: 20, bottom: 36, right: 20)
itemSize = CGSize(width: collectionView!.bounds.width - 40, height: 96)
var layoutInfo:[NSIndexPath:UICollectionViewLayoutAttributes] = [:]
let sections = collectionView!.numberOfSections()
for section in Range(start: 0, end: sections){
let items = collectionView!.numberOfItemsInSection(section)
for item in Range(start: 0, end: items){
// ignoreLast
if item == (items - 1){
continue
}
let indexPath = NSIndexPath(forItem: item, inSection: section)
layoutInfo[indexPath] = layoutAttributesForSeperatorAtIndexPath(indexPath)
}
}
seperatorLayoutInfo = layoutInfo
println("prepareLayout")
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
var attrsArray = super.layoutAttributesForElementsInRect(rect)
for attrs in seperatorLayoutInfo.values{
if attrs.frame.intersects(rect){
attrsArray?.append(attrs)
}
}
return attrsArray
}
override func layoutAttributesForDecorationViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
return seperatorLayoutInfo[indexPath]
}
// MARK:Helpers
func layoutAttributesForSeperatorAtIndexPath(indexPath:NSIndexPath) -> UICollectionViewLayoutAttributes{
let cellAttributes = layoutAttributesForItemAtIndexPath(indexPath)
let nextIndexPath = NSIndexPath(forItem: indexPath.item + 1, inSection: indexPath.section)
let nextCellAttributes = layoutAttributesForItemAtIndexPath(nextIndexPath)
var layoutAttributes = UICollectionViewLayoutAttributes(forDecorationViewOfKind: LayoutKinds.seperator, withIndexPath: indexPath)
let strokeWidth:CGFloat = 2;
let baseFrame = cellAttributes.frame
let lineSpacing = nextCellAttributes.frame.minY - baseFrame.maxY
let y = baseFrame.maxY + (lineSpacing - strokeWidth ) * 0.5
let frame = CGRect(x: baseFrame.origin.x, y: y, width: baseFrame.width, height: strokeWidth)
layoutAttributes.frame = frame
return layoutAttributes
}
}
let dataSource = TopicDataSource()
let layout = TopicFlowLayout()
let frame = CGRect(x: 0, y: 0, width: 320, height: 480)
let collectionView = UICollectionView(frame: frame, collectionViewLayout: layout)
collectionView.registerClass(TopicView.classForCoder(), forCellWithReuseIdentifier: TopicView.identifier)
collectionView.backgroundColor = backgroundColor
collectionView.dataSource = dataSource
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment