Skip to content

Instantly share code, notes, and snippets.

@Ridwy
Last active August 29, 2015 14:17
Show Gist options
  • Save Ridwy/8a2093de88384152b55d to your computer and use it in GitHub Desktop.
Save Ridwy/8a2093de88384152b55d to your computer and use it in GitHub Desktop.
User icon lining up view like FourSquare
//
// CNLiningUpView.swift
// CNLiningUpView
//
// Created by Chiharu Nameki on 2015/03/29.
// Copyright (c) 2015 Chiharu Nameki. All rights reserved.
//
import UIKit
class CNLiningUpItem {
let imageURL: NSURL?
let badgeImage: UIImage?
init(imageURL: NSURL? = nil, badgeImage: UIImage? = nil) {
self.imageURL = imageURL
self.badgeImage = badgeImage
}
}
class CNLiningUpItemView : UIView {
var imageView: UIImageView!
var badgeImageView: UIImageView!
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup() {
imageView = UIImageView(frame: bounds)
imageView.contentMode = .ScaleAspectFill
imageView.autoresizingMask = .FlexibleWidth | .FlexibleHeight
imageView.clipsToBounds = true
imageView.layer.cornerRadius = 2.0
self.addSubview(imageView)
badgeImageView = UIImageView(frame: CGRectMake(-2, -2, 10, 10))
badgeImageView.autoresizingMask = .FlexibleRightMargin | .FlexibleBottomMargin
self.addSubview(badgeImageView)
}
}
class CNLiningUpView : UIView {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
// data source
var items: [CNLiningUpItem] = []
var count: Int = 0
// appearances
var itemSize: CGSize = CGSizeMake(22, 22)
var itemPlaceholderImage: UIImage?
var margin: CGFloat = 4.0
var showsMoreItem = true
var badgeFrame: CGRect = CGRectMake(-2, -2, 10, 10)
func reloadData() {
update()
for (i, itemView) in enumerate(itemViews) {
if itemView.superview == nil {
break
}
configureItemView(itemView, item:items[i])
}
}
func generateItemView() -> UIView {
let view = CNLiningUpItemView(frame: CGRectMake(0, 0, itemSize.width, itemSize.height))
view.badgeImageView.frame = badgeFrame
return view
}
func configureItemView(itemView: UIView, item: CNLiningUpItem) {
if let itemView = itemView as? CNLiningUpItemView {
itemView.imageView.sd_setImageWithURL(item.imageURL,
placeholderImage: itemPlaceholderImage,
options: .CacheMemoryOnly)
itemView.badgeImageView.image = item.badgeImage
}
}
func generateMoreItemView() -> UIView {
let label = UILabel(frame: CGRectMake(0, 0, itemSize.width, itemSize.height))
label.font = UIFont.systemFontOfSize(itemSize.height * 0.38)
label.minimumScaleFactor = 0.5
label.textColor = UIColor.whiteColor()
label.textAlignment = .Center
label.backgroundColor = UIColor.grayColor()
return label
}
func configureMoreItemView(number: Int) {
if let label = moreItemView as? UILabel {
label.text = number < 100 ? "+\(number)" : "+lots"
}
}
private var itemViews: [UIView] = []
var moreItemView: UIView!
override func layoutSubviews() {
update()
}
private func update() {
let centerY = (bounds.size.height - itemSize.height) * 0.5
let max = Int((bounds.size.width + margin) / (itemSize.width + margin))
let needsMoreItem = { () -> Bool in
if self.showsMoreItem {
if self.items.count < self.count {
return true
}
if max < self.items.count {
return true
}
}
return false
}()
let n = min(min(items.count, count), max - (needsMoreItem ? 1 : 0))
for i in 0..<n {
if itemViews.count <= i {
let itemView = generateItemView()
itemViews.append(itemView)
configureItemView(itemView, item: items[i])
}
let view = itemViews[i]
view.frame = CGRectMake((itemSize.width + margin) * CGFloat(i), centerY, itemSize.width, itemSize.height)
if view.superview == nil {
addSubview(view)
}
}
if n < itemViews.count {
for i in n..<itemViews.count {
let view = itemViews[i]
view.removeFromSuperview()
}
}
if needsMoreItem {
if moreItemView == nil {
moreItemView = generateMoreItemView()
}
moreItemView.frame = CGRectMake((itemSize.width + margin) * CGFloat(n), centerY, itemSize.width, itemSize.height)
configureMoreItemView(count - n)
if moreItemView.superview == nil {
addSubview(moreItemView)
}
} else {
moreItemView?.removeFromSuperview()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment