Last active
October 20, 2017 01:42
-
-
Save monkeywithacupcake/3d05d779a1e7f44badc5ff0ece551185 to your computer and use it in GitHub Desktop.
Swift .playground showing how to programmatically change the height of items in a stack view and track cells selected and unselected.
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
//: Playground - noun: a place where people can play | |
import UIKit | |
import PlaygroundSupport | |
extension UIView { | |
func asCircle(){ | |
self.layer.cornerRadius = self.frame.width / 2; | |
self.layer.masksToBounds = true | |
} | |
} | |
class MyCollectionViewCell: UICollectionViewCell { | |
override func awakeFromNib() { | |
print("awakeFromNib") | |
} | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
self.asCircle() | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override var isHighlighted: Bool { | |
didSet { | |
if isHighlighted { | |
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseIn, animations: { | |
self.transform = CGAffineTransform(scaleX: 0.5, y: 0.7) | |
}, completion: nil) | |
} else { | |
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: { | |
self.transform = CGAffineTransform(scaleX: 1, y: 1) | |
}, completion: nil) | |
} | |
} | |
} | |
} | |
class MyViewController : UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, UICollectionViewDataSource { | |
// MARK: - Properties | |
// views | |
var headerView: UIView! | |
var titleLabel: UILabel! | |
var selView: UIView! | |
var selLabel: UILabel! | |
var collectionView: UICollectionView? | |
// attributes | |
var numberSelected = 0 // track this | |
// MARK: - LifeCycle | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
setupHeader() | |
setupCollection() | |
setupSelection() | |
setupStack() | |
} | |
// MARK: Methods | |
func updateSelectedCount(_ upOrDown:String) { | |
switch(upOrDown) { | |
case "up": | |
numberSelected += 1 | |
case "down": | |
if numberSelected > 0 { | |
numberSelected -= 1 | |
} | |
default: | |
print("not up or down") | |
} | |
} | |
// MARK: CollectionView Methods | |
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | |
return 40 | |
} | |
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { | |
return CGSize(width: 50.0, height: 50.0) | |
} | |
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { | |
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! MyCollectionViewCell | |
cell.backgroundColor = .black | |
return cell | |
} | |
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { | |
let selectedCell = collectionView.cellForItem(at: indexPath) | |
selectedCell?.backgroundColor = .blue | |
updateSelectedCount("up") | |
let selected = String(describing: indexPath.row + 1) | |
let selString = "You selected \(selected) for a total of \(numberSelected)" | |
selLabel.text = selString | |
} | |
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { | |
let deselectedCell = collectionView.cellForItem(at: indexPath) | |
deselectedCell?.backgroundColor = .gray | |
updateSelectedCount("down") | |
let deselected = String(describing: indexPath.row + 1) | |
let selString = "You deselected \(deselected) for a total of \(numberSelected)" | |
selLabel.text = selString | |
} | |
// MARK: SetUp Methods | |
func setupHeader() { | |
headerView = UIView() | |
headerView.backgroundColor = .white | |
titleLabel = UILabel() | |
titleLabel.text = "Update" | |
titleLabel.textAlignment = .center | |
titleLabel.font = UIFont(name: titleLabel.font.fontName, size: 20) | |
headerView.addSubview(titleLabel) | |
titleLabel.translatesAutoresizingMaskIntoConstraints = false | |
titleLabel.centerXAnchor.constraint(equalTo: headerView.centerXAnchor).isActive = true | |
titleLabel.centerYAnchor.constraint(equalTo: headerView.centerYAnchor).isActive = true | |
} | |
func setupCollection() { | |
let frame = self.view.frame | |
let layout = UICollectionViewFlowLayout() | |
collectionView = UICollectionView(frame: frame, collectionViewLayout: layout) | |
collectionView?.delegate = self | |
collectionView?.dataSource = self | |
self.collectionView?.backgroundColor = .white | |
self.collectionView?.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: "MyCell") | |
collectionView?.allowsMultipleSelection = true | |
} | |
func setupSelection() { | |
selView = UIView() | |
selView.backgroundColor = .white | |
selLabel = UILabel() | |
selLabel.text = "" | |
selLabel.numberOfLines = 0 | |
selLabel.lineBreakMode = .byWordWrapping | |
selLabel.textAlignment = .center | |
selLabel.font = UIFont(name: selLabel.font.fontName, size: 14) | |
selView.addSubview(selLabel) | |
selLabel.translatesAutoresizingMaskIntoConstraints = false | |
selLabel.centerXAnchor.constraint(equalTo: selView.centerXAnchor).isActive = true | |
selLabel.centerYAnchor.constraint(equalTo: selView.centerYAnchor).isActive = true | |
selLabel.widthAnchor.constraint(equalTo: selView.widthAnchor).isActive = true | |
} | |
func setupStack() { | |
let stackView = UIStackView(arrangedSubviews: [headerView, collectionView!, selView]) | |
stackView.axis = .vertical | |
stackView.distribution = .fill | |
stackView.alignment = .fill | |
stackView.spacing = 10 | |
stackView.translatesAutoresizingMaskIntoConstraints = false | |
// add some component constraints | |
let headHeight = headerView.heightAnchor.constraint(equalToConstant: 50) | |
let selHeight = selView.heightAnchor.constraint(equalToConstant: 50) | |
stackView.addConstraints([headHeight, selHeight]) | |
view.addSubview(stackView) | |
//autolayout the stack view | |
let sH = NSLayoutConstraint.constraints(withVisualFormat: "H:|-20-[stackView]-20-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["stackView":stackView]) | |
let sV = NSLayoutConstraint.constraints(withVisualFormat: "V:|-30-[stackView]-30-|", options: NSLayoutFormatOptions(rawValue:0), metrics: nil, views: ["stackView":stackView]) | |
view.addConstraints(sH) | |
view.addConstraints(sV) | |
} | |
} | |
PlaygroundPage.current.liveView = MyViewController() |
updated to add little spring animation on selection and deselection and to change "picked" to "selected" and "deselected" so that it is clear to users.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is how it looks: