Skip to content

Instantly share code, notes, and snippets.

@SatoshiN303
Created October 24, 2018 10:44
Show Gist options
  • Save SatoshiN303/6f2d48d9271242d3265ba57a070d240c to your computer and use it in GitHub Desktop.
Save SatoshiN303/6f2d48d9271242d3265ba57a070d240c to your computer and use it in GitHub Desktop.
WIP
import UIKit
import Foundation
import XCPlayground
import PlaygroundSupport
//protocol Pokemon {
// associatedtype PokemonType
// func attack(move: PokemonType) -> Void
//}
//
//class Electric {}
//class Fire {}
//
//class Pikachu: Pokemon {
// typealias PokemonType = Electric
// func attack(move: Electric) {
// print("⚡️")
// }
//}
//
//class Charmander: Pokemon {
// typealias PokemonType = Fire
// func attack(move: Fire) {
// print("🔥")
// }
//}
//
//let pika1: Pikachu = Pikachu()
//// Pokemonプロトコルに準拠してるのにPokemonTypeが決まってないのでコンパイルエラー
//// let pika2: Pokemon = Pikachu()
//
//class AnyPokemon<PokemonType>: Pokemon {
// private let _attack:((PokemonType) -> Void)
//
// required init<U:Pokemon>(_ pokemon: U) where U.PokemonType == PokemonType {
// self._attack = pokemon.attack
// }
//
// func attack(move: PokemonType) {
// return _attack(move)
// }
//}
//: Playground - noun: a place where people can play
// classを継承しないと ‘weak’ cannot be applied to non-class type というコンパイルエラー
// プロトコル、構造体、列挙体はweakにできないが、クラスおよびクラスを継承したものだけはweakに出来る。
protocol ViewControllerDelegate: class {
associatedtype Item
func collectionView(_ collectionView: UICollectionView, cellFor item: Item) -> UICollectionViewCell?
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeFor item: Item) -> CGSize?
func collectionView(_ collectionView: UICollectionView, didSelect item: Item)
func collectionView(_ collectionView: UICollectionView,
cellFor item: Item,
dequeue: ((_ identifier:String) -> UICollectionViewCell?)
) -> UICollectionViewCell?
}
// 型消去用クラス
class ViewControllerDelegateWrapper<Delegate: ViewControllerDelegate> {
private weak var delegate: Delegate?
init(delegate: Delegate) {
self.delegate = delegate
}
func collectionView(_ collectionView: UICollectionView, cellFor item: Delegate.Item) -> UICollectionViewCell? {
return delegate?.collectionView(collectionView, cellFor: item)
}
func collectionView(_ collectionView: UICollectionView,
cellFor item: Delegate.Item,
dequeue: ((_ identifier:String) -> UICollectionViewCell?)
) -> UICollectionViewCell? {
return delegate?.collectionView(collectionView, cellFor: item, dequeue: dequeue)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeFor item: Delegate.Item) -> CGSize? {
return delegate?.collectionView(collectionView, layout: collectionViewLayout, sizeFor: item)
}
func collectionView(_ collectionView: UICollectionView, didSelect item: Delegate.Item) {
self.delegate?.collectionView(collectionView, didSelect: item)
}
}
class ViewController<Delegate: ViewControllerDelegate>: UICollectionViewController, UICollectionViewDelegateFlowLayout {
//associatedtypeのItemが決定していないのでコンパイルエラー
//weak var delegate: MyViewControllerDelegate?
typealias CellRegisterHandler = ((_ cellClass: AnyClass, _ identifier: String) -> Void)
//型消去用のクラスをdelegateにしてGenericsに扱う
var delegate: ViewControllerDelegateWrapper<Delegate>?
var items = [Array<Delegate.Item>]()
//MARK: - initializer
init(_ delegate: ViewControllerDelegateWrapper<Delegate>, configure: CellRegisterHandler) {
super.init(collectionViewLayout: UICollectionViewFlowLayout())
self.delegate = delegate
let register: CellRegisterHandler = { [weak self] (cellClass: AnyClass, identifier: String) in
self?.collectionView.register(cellClass, forCellWithReuseIdentifier: identifier)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//MARK: - view lifecycle
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return items.count
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items[section].count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let item = items[indexPath.section][indexPath.row]
let dequeueHandler = dequeue(collectionView: collectionView, from: indexPath)
if let cell = delegate?.collectionView(collectionView, cellFor: item, dequeue: dequeueHandler) {
return cell
}
return collectionView.dequeueReusableCell(withReuseIdentifier: "Identifier", for: indexPath)
}
//MARK: - UICollectionViewDelegate
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let item = items[indexPath.section][indexPath.row]
delegate?.collectionView(collectionView, didSelect: item)
}
//MARK: - UICollectionViewLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let item = items[indexPath.section][indexPath.row]
if let size = delegate?.collectionView(collectionView, layout: collectionViewLayout, sizeFor: item) {
return size
}
return collectionViewLayout.collectionViewContentSize
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
//MARK: - MISC
private func dequeue(collectionView: UICollectionView, from indexPath: IndexPath)
-> ((_ identifier:String) -> UICollectionViewCell?) {
return { (_ identifier:String) -> UICollectionViewCell? in
return collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment