Created
October 24, 2018 10:44
-
-
Save SatoshiN303/6f2d48d9271242d3265ba57a070d240c to your computer and use it in GitHub Desktop.
WIP
This file contains hidden or 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
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