Slide 1

Slide 1 text

J04%$3FKFDU$POGFSFODF 6*$PMMFDUJPO7JFXͷσʔλߏ଄ͱ7JFXͷݟͨ໨Λ౷Ұ͢Δ

Slide 2

Slide 2 text

ࣗݾ঺հ *%CBOO[BJ ॴଐגࣜձࣾ"TPCJDB ৬ۀ&OHJOFFS ݺশελʔޤ৯ CBOO[BJ @CBOO[BJ@

Slide 3

Slide 3 text

લஔ͖ IUUQTGPSUFFKQJPTEDKBQBOQSPQPTBMBBEBBBCBB ⒎FBEG

Slide 4

Slide 4 text

$POWͱ͍͏ϥΠϒϥϦΛ࡞Γ·ͨ͠ (JU)VCϦϙδτϦ IUUQTHJUIVCDPNCBOO[BJ$POW 2JJUBʹ΋ಉ͡λΠτϧͰهࣄΛॻ͍ͨ IUUQTRJJUBDPNCBOO[BJJUFNTGECFDDBECF

Slide 5

Slide 5 text

$POWͬͯʁ

Slide 6

Slide 6 text

ैདྷͷॻ͖ํ public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { switch section { case 0: return users.count case 1: return hobbies.count case 2: return teams.count default: fatalError() } } public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { switch (indexPath.section, indexPath.item) { case (0, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ACell", for: indexPath) as! UserCell cell.configure(with: users[indexPath.item]) ... return cell case (1, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BCell", for: indexPath) as! HobbyCell cell.configure(with: hobbies[indexPath.item]) ... return cell case (2, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CCell", for: indexPath) as! TeamCell cell.configure(with: teams[indexPath.item]) ... return cell default: fatalError() } }

Slide 7

Slide 7 text

ैདྷͷॻ͖ํ public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { switch section { case 0: return users.count case 1: return hobbies.count case 2: return teams.count default: fatalError() } } public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { switch (indexPath.section, indexPath.item) { case (0, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ACell", for: indexPath) as! UserCell cell.configure(with: users[indexPath.item]) ... return cell case (1, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BCell", for: indexPath) as! HobbyCell cell.configure(with: hobbies[indexPath.item]) ... return cell case (2, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CCell", for: indexPath) as! TeamCell cell.configure(with: teams[indexPath.item]) ... return cell default: fatalError() } } ύλʔϯϚον͠ͳ͍৔߹ͷGBUBM&SSPS

Slide 8

Slide 8 text

ैདྷͷॻ͖ํ public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { switch section { case 0: return users.count case 1: return hobbies.count case 2: return teams.count default: fatalError() } } public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { switch (indexPath.section, indexPath.item) { case (0, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ACell", for: indexPath) as! UserCell cell.configure(with: users[indexPath.item]) ... return cell case (1, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BCell", for: indexPath) as! HobbyCell cell.configure(with: hobbies[indexPath.item]) ... return cell case (2, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CCell", for: indexPath) as! TeamCell cell.configure(with: teams[indexPath.item]) ... return cell default: fatalError() } } ࢄΒ͹Δ'PSDFVOXSBQ

Slide 9

Slide 9 text

ैདྷͷॻ͖ํ public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { switch section { case 0: return users.count case 1: return hobbies.count case 2: return teams.count default: fatalError() } } public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { switch (indexPath.section, indexPath.item) { case (0, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ACell", for: indexPath) as! UserCell cell.configure(with: users[indexPath.item]) ... return cell case (1, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BCell", for: indexPath) as! HobbyCell cell.configure(with: hobbies[indexPath.item]) ... return cell case (2, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CCell", for: indexPath) as! TeamCell cell.configure(with: teams[indexPath.item]) ... return cell default: fatalError() } } ͲΕ͕ͲΕ

Slide 10

Slide 10 text

ैདྷͷॻ͖ํ public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { switch section { case 0: return users.count case 1: return hobbies.count case 2: return teams.count default: fatalError() } } public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { switch (indexPath.section, indexPath.item) { case (0, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ACell", for: indexPath) as! UserCell cell.configure(with: users[indexPath.item]) ... return cell case (1, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BCell", for: indexPath) as! HobbyCell cell.configure(with: hobbies[indexPath.item]) ... return cell case (2, _): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CCell", for: indexPath) as! TeamCell cell.configure(with: teams[indexPath.item]) ... return cell default: fatalError() } } ཁૉͷؔ܎ੑ͕ബ͍ɾԕ͍

Slide 11

Slide 11 text

$POWΛ࢖͏ͱ

Slide 12

Slide 12 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } }

Slide 13

Slide 13 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } } ͜ΕͰ࡞Εͯ͠·͍·͢

Slide 14

Slide 14 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } } ͚ͩ͜͜&OVNΛҰ͚ͭͩఆٛͨ͠

Slide 15

Slide 15 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } } ഑ྻΛ౉ͨ͠਺͚ͩ4FDUJPO͕࡞ΒΕΔ

Slide 16

Slide 16 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } } ഑ྻͷཁૉ͝ͱʹ4FDUJPOΛఆٛ͢ΔͷͰ *OEFY1BUIʹΞΫηε͠ͳ͍͍ͯ͘

Slide 17

Slide 17 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } } 4FDUJPOʹ౉ͨ͠਺͚ͩ*UFN͕࡞ΒΕΔ

Slide 18

Slide 18 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } } ഑ྻͷཁૉ͝ͱʹ*UFNΛఆٛ͢ΔͷͰ *OEFY1BUIʹΞΫηε͠ͳ͍͍ͯ͘

Slide 19

Slide 19 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } } $FMM͝ͱͷ%BUB4PVSDFɾ%FMFHBUFͷϝιουͷϥούʔୡ

Slide 20

Slide 20 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } } (FOFSJDTͰΩϟετ͞Εͨ$FMM͕౉ͬͯ͘Δ

Slide 21

Slide 21 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } } 4FDUJPOͱ*UFNͷؔ܎ੑ͕໌֬ʹɻݶఆతʹ

Slide 22

Slide 22 text

collectionView .conv() .create(for: SectionType.allCases) { (sectionType, section) in // ※2 switch sectionType { case .users: section.create(for: users) { user, item: Item in item.reusableIdentifier = "ACell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: user) }) } case .hobbies: section.create(for: hobbies) { hobby, item: Item in item.reusableIdentifier = "BCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: hobby) }) } case .teams: section.create(for: teams) { team, item: Item in item.reusableIdentifier = "CCell" item.size = ... item.configureCell({ cell, _ in cell.configure(with: team) }) } } } ແବͳGBUBM&SSPS͕ͳ͘ͳ͍ͬͯΔ

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

͍͍͡ΌΜ

Slide 25

Slide 25 text

͍͍͘͢͝

Slide 26

Slide 26 text

࠷ߴ

Slide 27

Slide 27 text

ࠩ෼ߋ৽ $POWͰ͸ࠩ෼ߋ৽ͷΞϧΰϦζϜͱͯ͠ 1BVM)FDLFMTBMHPSJUINΛϕʔεͱͯ͠࡞͍ͬͯ ·͢ɻͳͷͰඞཁͳ෦෼͚ͩߋ৽͢ΔͷͰແବͳॲཧ ͕ͳ͍ *(-JTU,JU͕ಉ͡ΞϧΰϦζϜ࢖͍ͬͯΔ IUUQTHJUIVCDPN*OTUBHSBN*(-JTU,JU

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

४උ public protocol Differenciable { var differenceIdentifier: DifferenceIdentifier { get } }

Slide 30

Slide 30 text

4FDUJPO enum SectionType: Int { case one case two case three static var allCases: [SectionType] { return [.one, .two, .three] } } extension SectionType: Differenciable { var differenceIdentifier: DifferenceIdentifier { return "\(self)" } }

Slide 31

Slide 31 text

*UFN struct ItemModel { let imageName: String var image: UIImage { return UIImage(named: imageName)! } } extension ItemModel: Differenciable { var differenceIdentifier: DifferenceIdentifier { return imageName } }

Slide 32

Slide 32 text

"SSBZ let sectionTypes = SectionType.allCases let itemModels = ["forest", "moon", “mountain"] .map { ImageModel(imageName: $0) }

Slide 33

Slide 33 text

$POW collectionView .conv() .create(for: sectionTypes) { (sectionType, section) in section.create(.header, headerOrFooter: { (header: SectionHeaderFooter) in header.reusableIdentifier = "Header" header.size = CGSize(width: UIScreen.main.bounds.width, height: 50) header.configureView { view, _ in view.nameLabel.text = "\(sectionType)".uppercased() view.nameLabel.textColor = .white view.backgroundColor = sectionType.backgroundColor } }) section.create(for: itemModels, items: { (itemModel, item: Item) in item.reusableIdentifier = "Cell" item.sizeFor { (item, collectionView, indexPath) -> CGSize in let gridCount: CGFloat = 3 let edge = floor((collectionView.bounds.width - (gridCount - 1)) / gridCount) let size = CGSize(width: edge, height: edge) return size } item.configureCell { (cell, info) in cell.setup(with: itemModel) } item.didSelect { [weak self] (item) in let viewController = DetailViewController(imageName: itemModel.imageName) self?.navigationController?.pushViewController(viewController, animated: true) } }) }

Slide 34

Slide 34 text

͜ΕͰࠩ෼ߋ৽ collectionView.update()

Slide 35

Slide 35 text

SFMPBE%BUB collectionView.reload()

Slide 36

Slide 36 text

͓ΘΓʹ (JU)VCϦϙδτϦ IUUQTHJUIVCDPNCBOO[BJ$POW 2JJUBʹ΋ಉ͡λΠτϧͰهࣄΛॻ͍ͨ IUUQTRJJUBDPNCBOO[BJJUFNTGECFDDBECF ελʔ͍ͩ͘͞

Slide 37

Slide 37 text

͓͠·͍a ?P?