GBA001/Delta/Pause Menu/GridMenuViewController.swift

177 lines
5.5 KiB
Swift

//
// GridMenuViewController.swift
// Delta
//
// Created by Riley Testut on 12/21/15.
// Copyright © 2015 Riley Testut. All rights reserved.
//
import UIKit
import Roxas
class GridMenuViewController: UICollectionViewController
{
var items: [MenuItem] {
get { return self.dataSource.items }
set { self.dataSource.items = newValue; self.updateItems() }
}
var isVibrancyEnabled = true
override var preferredContentSize: CGSize {
set { }
get { return self.collectionView?.contentSize ?? CGSize.zero }
}
private let dataSource = RSTArrayCollectionViewDataSource<MenuItem>(items: [])
private var prototypeCell = GridCollectionViewCell()
private var previousIndexPath: IndexPath? = nil
private var registeredKVOObservers = Set<NSKeyValueObservation>()
init()
{
let collectionViewLayout = GridCollectionViewLayout()
collectionViewLayout.itemSize = CGSize(width: 60, height: 80)
collectionViewLayout.minimumLineSpacing = 20
collectionViewLayout.minimumInteritemSpacing = 10
super.init(collectionViewLayout: collectionViewLayout)
}
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}
deinit
{
// Crashes on iOS 10 if not explicitly invalidated.
self.registeredKVOObservers.forEach { $0.invalidate() }
}
}
extension GridMenuViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
self.collectionView?.register(GridCollectionViewCell.self, forCellWithReuseIdentifier: RSTCellContentGenericCellIdentifier)
self.dataSource.cellConfigurationHandler = { [unowned self] (cell, item, indexPath) in
self.configure(cell as! GridCollectionViewCell, for: indexPath)
}
self.collectionView?.dataSource = self.dataSource
let collectionViewLayout = self.collectionViewLayout as! GridCollectionViewLayout
collectionViewLayout.itemWidth = 90
collectionViewLayout.usesEqualHorizontalSpacingDistributionForSingleRow = true
// Manually update prototype cell properties
self.prototypeCell.contentView.widthAnchor.constraint(equalToConstant: collectionViewLayout.itemWidth).isActive = true
}
override func viewDidAppear(_ animated: Bool)
{
super.viewDidAppear(animated)
if let indexPath = self.previousIndexPath
{
UIView.animate(withDuration: 0.2) {
let item = self.items[indexPath.item]
item.isSelected = !item.isSelected
}
}
}
}
private extension GridMenuViewController
{
func configure(_ cell: GridCollectionViewCell, for indexPath: IndexPath)
{
let pauseItem = self.items[indexPath.item]
cell.maximumImageSize = CGSize(width: 60, height: 60)
cell.imageView.image = pauseItem.image
cell.imageView.contentMode = .center
cell.imageView.layer.borderWidth = 2
cell.imageView.layer.borderColor = self.view.tintColor.cgColor
cell.imageView.layer.cornerRadius = 10
cell.textLabel.text = pauseItem.text
cell.textLabel.textColor = self.view.tintColor
if pauseItem.isSelected
{
cell.imageView.tintColor = UIColor.black
cell.imageView.backgroundColor = self.view.tintColor
}
else
{
cell.imageView.tintColor = self.view.tintColor
cell.imageView.backgroundColor = UIColor.clear
}
cell.isImageViewVibrancyEnabled = self.isVibrancyEnabled
cell.isTextLabelVibrancyEnabled = self.isVibrancyEnabled
}
func updateItems()
{
self.registeredKVOObservers.removeAll()
for (index, item) in self.items.enumerated()
{
let observer = item.observe(\.isSelected, changeHandler: { [unowned self] (item, change) in
let indexPath = IndexPath(item: index, section: 0)
if let cell = self.collectionView?.cellForItem(at: indexPath) as? GridCollectionViewCell
{
self.configure(cell, for: indexPath)
}
})
self.registeredKVOObservers.insert(observer)
}
}
}
extension GridMenuViewController: UICollectionViewDelegateFlowLayout
{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
self.configure(self.prototypeCell, for: indexPath)
let size = self.prototypeCell.contentView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
return size
}
}
extension GridMenuViewController
{
override func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath)
{
let item = self.items[indexPath.item]
item.isSelected = !item.isSelected
}
override func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath)
{
let item = self.items[indexPath.item]
item.isSelected = !item.isSelected
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
self.previousIndexPath = indexPath
let item = self.items[indexPath.item]
item.isSelected = !item.isSelected
item.action(item)
}
}