{"id":266,"date":"2021-05-03T11:44:53","date_gmt":"2021-05-03T02:44:53","guid":{"rendered":"https:\/\/tech.for-easy-learning.com\/?p=266"},"modified":"2021-05-03T12:00:57","modified_gmt":"2021-05-03T03:00:57","slug":"%e3%80%90ios-swift%e3%80%91iglistkit-%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab%e3%81%ae-gridsectioncontroller-%e3%82%92%e4%b8%80%e8%88%ac%e5%8c%96%e3%81%99%e3%82%8b","status":"publish","type":"post","link":"https:\/\/tech.for-easy-learning.com\/?p=266","title":{"rendered":"\u3010iOS\/Swift\u3011IGListKit \u30b5\u30f3\u30d7\u30eb\u306e GridSectionController \u3092\u4e00\u822c\u5316\u3059\u308b"},"content":{"rendered":"\n<p>Instagram \u306e iOS \u30c1\u30fc\u30e0\u304c\u958b\u767a\u3057\u3066\u3044\u308b CollectionView \u3092\u4fbf\u5229\u306b\u6271\u3046\u305f\u3081\u306e OSS \u3068\u3057\u3066 <a href=\"https:\/\/github.com\/Instagram\/IGListKit\" data-type=\"URL\" data-id=\"https:\/\/github.com\/Instagram\/IGListKit\">IGListKit<\/a> \u304c\u3042\u308a\u307e\u3059\u3002\u30ea\u30b9\u30c8\u306e\u9014\u4e2d\u306b\u5e83\u544a\u3084\u4ed6\u306e\u5dee\u8fbc\u307f\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u5165\u308c\u305f\u3044\u6642\u306b\u3068\u3066\u3082\u4fbf\u5229\u3067\u9577\u5e74\u611b\u7528\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u3068\u306f\u8a00\u3048 SwiftUI \u304c\u3044\u3044\u611f\u3058\u306b\u306a\u3063\u3066\u304d\u305f\u306e\u3067\u3042\u30681\u5e74\u304f\u3089\u3044\u3067 IGListKit \u3082\u4f7f\u308f\u306a\u304f\u306a\u308a\u305d\u3046\u306a\u306e\u3060\u3051\u3069&#8230;\u3002<\/p>\n\n\n\n<p>\u3067\u3001\u4eca\u56de\u306f IGListKit \u306e\u30b5\u30f3\u30d7\u30eb\u306b\u3042\u308b <a href=\"https:\/\/github.com\/Instagram\/IGListKit\/blob\/master\/Examples\/Examples-iOS\/IGListKitExamples\/SectionControllers\/GridSectionController.swift\" data-type=\"URL\" data-id=\"https:\/\/github.com\/Instagram\/IGListKit\/blob\/master\/Examples\/Examples-iOS\/IGListKitExamples\/SectionControllers\/GridSectionController.swift\">GridSectionController<\/a> \u3092\u4e00\u822c\u5316\u3057\u3066 <a href=\"https:\/\/github.com\/Instagram\/IGListKit\/blob\/master\/Source\/IGListKit\/IGListSingleSectionController.m\" data-type=\"URL\" data-id=\"https:\/\/github.com\/Instagram\/IGListKit\/blob\/master\/Source\/IGListKit\/IGListSingleSectionController.m\">ListSingleSectionController<\/a> \u306e\u3088\u3046\u306b\u5358\u4e00\u306e Cell \u3092\u7c21\u5358\u306b\u6271\u3048\u308b\u30af\u30e9\u30b9\u306e<strong>\u30de\u30eb\u30c1\u30ab\u30e9\u30e0\u7248<\/strong>\u3068\u3057\u3066\u4f5c\u308a\u307e\u3059\u3002\u3068\u8a00\u3063\u3066\u3082 <a href=\"https:\/\/github.com\/Instagram\/IGListKit\/blob\/master\/Source\/IGListKit\/IGListSingleSectionController.h#L38-L42\" data-type=\"URL\" data-id=\"https:\/\/github.com\/Instagram\/IGListKit\/blob\/master\/Source\/IGListKit\/IGListSingleSectionController.h#L38-L42\">ListSingleSectionControllerDelegate<\/a> \u306f\u4f5c\u6210\u305b\u305a\u306b didSelectItem \u3060\u3051\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u3059\u308b\u306e\u3067\u7c21\u6613\u7248\u3067\u3059\u306d\u3002<\/p>\n\n\n\n<p>\u307e\u305a\u306f\u30b3\u30f3\u30c6\u30f3\u30c4\u3068\u3057\u3066\u8868\u793a\u3059\u308b\u305f\u3081\u306e\u60c5\u5831\u3092\u6301\u3063\u305f GridItem \u3092\u5b9a\u7fa9\u3057\u307e\u3059\uff08ListDiffable \u306b\u6e96\u62e0\u3057\u3066\u3044\u308c\u3070\u306a\u3093\u3067\u3082\u3044\u3044\u306e\u3067\u5272\u611b\u3057\u307e\u3059\uff09\u3002<br>\u6c4e\u7528\u6027\u3092\u8003\u3048\u308b\u3068 class \u3067\u306f\u306a\u304f\u3066 protocol \u306b\u3057\u3066\u3082\u826f\u3044\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"toolbar:1 lang:swift decode:true \" title=\"GridItem\" >class GridItem: NSObject: ListDiffable {\n\/\/ \u5272\u611b\n}<\/pre><\/div>\n\n\n\n<p>\u7d9a\u3044\u3066\u305d\u306e GridItem \u3092\u683c\u7d0d\u3059\u308b\u305f\u3081\u306e\u5165\u308c\u7269\u3092\u7528\u610f\u3057\u307e\u3059\u3002\u3053\u306e\u30af\u30e9\u30b9\u81ea\u4f53\u306f\u30b5\u30f3\u30d7\u30eb\u306b\u3042\u3063\u305f\u901a\u308a\u306e\u5b9f\u88c5\u3067\u540d\u524d\u3060\u3051\u5206\u304b\u308a\u3065\u3089\u3044\u306e\u3067 Container \u3068\u3044\u3046\u30ef\u30fc\u30c9\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059\u3002 ListDiffable \u306b\u6e96\u62e0\u3057\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u306e\u3067\u3053\u3046\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"toolbar:1 lang:swift decode:true \" title=\"GridItem \u3092\u683c\u7d0d\u3059\u308b\u30af\u30e9\u30b9\" >final class GridItemContainer: NSObject {\n  let items: [GridItem]\n  init(items: [GridItem]) {\n    self.items = items\n    super.init()\n  }\n}\n\nextension GridItemContainer: ListDiffable {\n  func diffIdentifier() -&gt; NSObjectProtocol {\n    return self\n  }\n  \n  func isEqual(toDiffableObject object: ListDiffable?) -&gt; Bool {\n    return self === object ? true : self.isEqual(object)\n  }\n}<\/pre><\/div>\n\n\n\n<p><br>\u3053\u308c\u3067 GridItemContainer \u304c GridItem \u306e\u30ea\u30b9\u30c8\u3092\u6301\u3063\u3066\u3044\u308b\u306e\u3067\u3001ListSectionController \u3067\u9069\u5207\u306b numberOfItems() \u3092 override \u3059\u308c\u3070 GridItem \u304c Grid \u8868\u793a\u3055\u308c\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002\u305d\u306e\u305f\u3081\u306e SectionController \u5b9f\u88c5\u306f\u3053\u3093\u306a\u611f\u3058\u3067\u3059\u3002<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"toolbar:1 lang:swift decode:true \" title=\"GridSingleSectionController\" >final class GridSingleSectionController&lt;T: UICollectionViewCell&gt;: ListSectionController {\n  typealias DidSelectBlock = (Int, GridItem) -&gt; ()\n  private var object: GridItemContainer?\n  private var configureBlock: ListSingleSectionCellConfigureBlock\n  private var sizeBlock: ListSingleSectionCellSizeBlock\n  private var didSelectBlock: DidSelectBlock?\n  private var nibName: String?\n  private var bundle: Bundle?\n  \n  init(configureBlock: @escaping ListSingleSectionCellConfigureBlock, sizeBlock: @escaping ListSingleSectionCellSizeBlock, didSelect: DidSelectBlock? = nil) {\n    self.configureBlock = configureBlock\n    self.sizeBlock = sizeBlock\n    self.didSelectBlock = didSelect\n    super.init()\n    self.minimumLineSpacing = 1\n    self.minimumInteritemSpacing = 1\n  }\n  \n  init(nibName: String, bundle: Bundle?, configureBlock: @escaping ListSingleSectionCellConfigureBlock, sizeBlock: @escaping ListSingleSectionCellSizeBlock, didSelect: DidSelectBlock? = nil) {\n    self.nibName = nibName\n    self.bundle = bundle\n    self.configureBlock = configureBlock\n    self.sizeBlock = sizeBlock\n    self.didSelectBlock = didSelect\n    super.init()\n    self.minimumLineSpacing = 1\n    self.minimumInteritemSpacing = 1\n  }\n  \n  override func numberOfItems() -&gt; Int {\n    return object?.items.count ?? 0\n  }\n  \n  override func sizeForItem(at index: Int) -&gt; CGSize {\n    guard let object = object, index &lt; object.items.count else { return .zero }\n    return sizeBlock(object.items[index], collectionContext!)\n  }\n  \n  override func cellForItem(at index: Int) -&gt; UICollectionViewCell {\n    let cell: UICollectionViewCell\n    if let nibName = nibName {\n      cell = collectionContext!.dequeueReusableCell(withNibName: nibName, bundle: bundle, for: self, at: index)\n    } else {\n      cell = collectionContext!.dequeueReusableCell(of: T.self, for: self, at: index)\n    }\n    guard let object = object, index &lt; object.items.count else { return cell }\n    configureBlock(object.items[index], cell)\n    return cell\n  }\n  \n  override func didSelectItem(at index: Int) {\n    guard let object = object, index &lt; object.items.count else { return }\n    didSelectBlock?(index, object.items[index])\n  }\n  \n  override func didUpdate(to object: Any) {\n    self.object = object as? GridItemContainer\n  }\n}<\/pre><\/div>\n\n\n\n<p><br><a href=\"https:\/\/github.com\/Instagram\/IGListKit\/blob\/master\/Examples\/Examples-iOS\/IGListKitExamples\/SectionControllers\/GridSectionController.swift\" data-type=\"URL\" data-id=\"https:\/\/github.com\/Instagram\/IGListKit\/blob\/master\/Examples\/Examples-iOS\/IGListKitExamples\/SectionControllers\/GridSectionController.swift\">GridSectionController<\/a> \u3068 <a href=\"https:\/\/github.com\/Instagram\/IGListKit\/blob\/master\/Source\/IGListKit\/IGListSingleSectionController.m\" data-type=\"URL\" data-id=\"https:\/\/github.com\/Instagram\/IGListKit\/blob\/master\/Source\/IGListKit\/IGListSingleSectionController.m\">ListSingleSectionController<\/a> \u306e\u5b9f\u88c5\u3092\u898b\u3066\u3044\u305f\u3060\u3051\u308c\u3070\u308f\u304b\u308b\u901a\u308a\u30012\u3064\u3092\u639b\u3051\u5408\u308f\u305b\u305f\u3060\u3051\u3067\u3059\u3002\u79c1\u306f\u4f7f\u308f\u306a\u3044\u306e\u3067 delegate \u3068 storyboard \u306f\u7701\u7565\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u4f7f\u3044\u65b9\u306f ListSingleSectionController \u3068\u307b\u307c\u540c\u3058\u304f\u3001ItemCell \u3068\u3044\u3046 Cell \u3092\u8868\u793a\u3059\u308b\u5834\u5408\u306e\u4f7f\u7528\u4f8b\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"toolbar:1 lang:swift decode:true \" title=\"dataSource \u306e\u62e1\u5f35\u90e8\u5206\" >extension XXXDataSource: ListAdapterDataSource {\n  func objects(for listAdapter: ListAdapter) -&gt; [ListDiffable] {\n    return [GridItemContainer(items: objects)]\n  }\n\n  func emptyView(for listAdapter: ListAdapter) -&gt; UIView? {\n    return nil\n  }\n  \n  func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -&gt; ListSectionController {\n    let configureBlock = { (item: Any, cell: UICollectionViewCell) in\n      guard let cell = cell as? ItemCell else { return }\n      guard let model = item as? GridItem else { return }\n      \/\/ GridItem \u306e\u60c5\u5831\u3092\u4f7f\u3063\u3066 cell \u306e\u63cf\u753b\u51e6\u7406\n    }\n    \n    let sizeBlock = { [weak self] (item: Any, context: ListCollectionContext?) -&gt; CGSize in\n      guard let context = context else { return .zero }\n      return CGSize(width: context.containerSize.width \/ 3 - 1, height: 100) \/\/ \u5206\u5272\u65703\n    }\n    \n    let didSelectBlock = { [weak self] (index: Int, item: GridItem) in\n      print(\"tapped item of index: \\(index)\")\n    }\n    \n    return GridSingleSectionController&lt;ItemCell&gt;(\n      configureBlock: configureBlock,\n      sizeBlock: sizeBlock,\n      didSelect: didSelectBlock)\n  }\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>\u30dd\u30a4\u30f3\u30c8\u306f <code>objects(for:)<\/code> \u306b\u3066 GridItemContainer \u306e\u30ea\u30b9\u30c8\u3092\u8fd4\u3059\u70b9\u3068\u3001sizeBlock \u3067\u5229\u7528\u3059\u308b\u5074\u306e\u90fd\u5408\u3067\u5206\u5272\u6570\u3092\u81ea\u7531\u306b\u5909\u66f4\u3067\u304d\u308b\u70b9\u3067\u3057\u3087\u3046\u304b\u3002self \u3092\u30ad\u30e3\u30d7\u30c1\u30e3\u3059\u308b\u5834\u5408\u306f\u9069\u5207\u306b weak self \u306a\u308a\u3057\u3066\u5faa\u74b0\u53c2\u7167\u5bfe\u7b56\u3092\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n\n\n\n<p>\u4ee5\u4e0a\u3067\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Instagram \u306e iOS \u30c1\u30fc\u30e0\u304c\u958b\u767a\u3057\u3066\u3044\u308b CollectionView \u3092\u4fbf\u5229\u306b\u6271\u3046\u305f\u3081\u306e OSS \u3068\u3057\u3066 IGListKit \u304c\u3042\u308a\u307e\u3059\u3002\u30ea\u30b9\u30c8\u306e\u9014\u4e2d\u306b\u5e83\u544a\u3084\u4ed6\u306e\u5dee\u8fbc\u307f\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u5165\u308c\u305f\u3044\u6642\u306b\u3068\u3066\u3082\u4fbf\u5229\u3067\u9577&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"spay_email":""},"categories":[12],"tags":[13],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":264,"url":"https:\/\/tech.for-easy-learning.com\/?p=264","url_meta":{"origin":266,"position":0},"title":"\u3010iOS\/Swift\u3011Realm \u3067\u30c7\u30fc\u30bf\u3092\u78ba\u8a8d\u3059\u308b","date":"2021\u5e745\u67083\u65e5","format":false,"excerpt":"iOS \u3067\u624b\u8efd\u306b\u30c7\u30fc\u30bf\u3092\u6c38\u7d9a\u5316\u3059\u308b\u5834\u5408 UserDefaults \u304c\u4e00\u822c\u7684\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u304c\u3001\u5927\u91cf\u306e\u30c7\u2026","rel":"","context":"Swift","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":27,"url":"https:\/\/tech.for-easy-learning.com\/?p=27","url_meta":{"origin":266,"position":1},"title":"\u3010SQLite\u3011phpLiteAdmin\u3092\u4f7f\u3046","date":"2021\u5e744\u670826\u65e5","format":false,"excerpt":"\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u3057\u3066 MySQL \u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306b\u306f phpMyAdmin \u3092\u4f7f\u3044\u307e\u3059\u304c SQLite\u2026","rel":"","context":"SQLite","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":180,"url":"https:\/\/tech.for-easy-learning.com\/?p=180","url_meta":{"origin":266,"position":2},"title":"\u3010Web\u5168\u822c\u3011URL \u304c &#8216;\/\/&#8217; \u304b\u3089\u59cb\u307e\u3063\u3066\u3044\u308b href \u3084 source \u306e\u8b0e","date":"2021\u5e744\u670829\u65e5","format":false,"excerpt":"Web\u95a2\u9023\u306e\u958b\u767a\u3092\u3057\u3066\u3044\u308b\u3068\u983b\u7e41\u306b\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u30b9\u30e9\u30c3\u30b7\u30e5\u304c2\u3064\u4e26\u3093\u3067\u3044\u308b '\/\/' \u304b\u3089\u59cb\u307e\u308b UR\u2026","rel":"","context":"Web\u5168\u822c","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":8,"url":"https:\/\/tech.for-easy-learning.com\/?p=8","url_meta":{"origin":266,"position":3},"title":"\u3010WordPress\u3011mac \u306e\u30ed\u30fc\u30ab\u30eb\u74b0\u5883\u306b WordPress \u3092\u69cb\u7bc9\u3059\u308b","date":"2021\u5e744\u670827\u65e5","format":false,"excerpt":"WordPress \u3067\u30b5\u30a4\u30c8\u69cb\u7bc9\u3092\u9032\u3081\u308b\u5834\u5408\u3001\u30ec\u30f3\u30bf\u30eb\u30b5\u30fc\u30d0\u30fc\u3092\u5951\u7d04\u3059\u308b\u3053\u3068\u304b\u3089\u59cb\u3081\u306a\u3051\u308c\u3070\u3044\u3051\u306a\u3044\u2026","rel":"","context":"Web\u5168\u822c","img":{"alt_text":"","src":"https:\/\/i1.wp.com\/tech.for-easy-learning.com\/wp-content\/uploads\/2021\/04\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2021-04-27-9.14.10.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":63,"url":"https:\/\/tech.for-easy-learning.com\/?p=63","url_meta":{"origin":266,"position":4},"title":"\u3010PHP\u3011\u6b63\u898f\u8868\u73fe\u3092\u7528\u3044\u3066\u6587\u5b57\u5217\u3092\u64cd\u4f5c\u3059\u308b","date":"2021\u5e744\u670823\u65e5","format":false,"excerpt":"PHP \u3067\u6b63\u898f\u8868\u73fe\u3092\u4f7f\u3046\u5834\u5408\u3001\u4ee5\u4e0b\u306e PCRE\u95a2\u6570 \u304c\u7528\u610f\u3055\u308c\u3066\u3044\u308b\u306e\u3067\u76ee\u7684\u306b\u5fdc\u3058\u3066\u4f7f\u3044\u5206\u3051\u308b\u3002 \u95a2\u2026","rel":"","context":"PHP","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":19,"url":"https:\/\/tech.for-easy-learning.com\/?p=19","url_meta":{"origin":266,"position":5},"title":"\u3010WordPress\u3011\u30b5\u30d6\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u304a\u3044\u305fWordPress\u3092\u30eb\u30fc\u30c8\u306b\u8a2d\u5b9a\u3059\u308b","date":"2021\u5e744\u670826\u65e5","format":false,"excerpt":"\u30cd\u30c3\u30c8\u306b\u51fa\u56de\u3063\u3066\u3044\u308b WordPress \u306e\u8a2d\u5b9a\u3067\u306f\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066\u304d\u305f wordpress \u30d5\u30a9\u30eb\u2026","rel":"","context":"WordPress","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/tech.for-easy-learning.com\/index.php?rest_route=\/wp\/v2\/posts\/266"}],"collection":[{"href":"https:\/\/tech.for-easy-learning.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tech.for-easy-learning.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tech.for-easy-learning.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tech.for-easy-learning.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=266"}],"version-history":[{"count":7,"href":"https:\/\/tech.for-easy-learning.com\/index.php?rest_route=\/wp\/v2\/posts\/266\/revisions"}],"predecessor-version":[{"id":273,"href":"https:\/\/tech.for-easy-learning.com\/index.php?rest_route=\/wp\/v2\/posts\/266\/revisions\/273"}],"wp:attachment":[{"href":"https:\/\/tech.for-easy-learning.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=266"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tech.for-easy-learning.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=266"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tech.for-easy-learning.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=266"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}