Skip to content

Commit

Permalink
Support cells created from nibs
Browse files Browse the repository at this point in the history
Summary:
I started working on adding support for dequeuing cells created from nibs (issue #1). Additionally I extended `IGListSingleSectionController` so that it can be used with nibs too. I don't know if you had this also in mind.

- [x]  I'm currently thinking about the best way to test these changes.
- [x] I was not able to update the documentation (issue #55).

- [x] All tests pass. Demo project builds and runs.
- [x] I added tests, an experiment, or detailed why my change isn't tested.
- [x] I have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/master/CONTRIBUTING.md)
Closes #56

Reviewed By: dshahidehpour

Differential Revision: D4023746

Pulled By: rnystrom

fbshipit-source-id: 6a8b4cfb4dba38ea6e9870a9a4506288ee155cfe
  • Loading branch information
svenbacia authored and Facebook Github Bot committed Oct 15, 2016
1 parent 221c2fb commit ce4b851
Show file tree
Hide file tree
Showing 32 changed files with 682 additions and 144 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@

The changelog for `IGListKit`. Also see the [releases](https://github.com/instagram/IGListKit/releases) on GitHub.

## Master
1.1.0
-----

### Enhancements

- Fixed `-[IGListAdapter reloadDataWithCompletion:]` not returning early when `collectionView` or `dataSource` is nil and `completion` is nil. [Ben Asher](https://github.com/benasher44) [#51](https://github.com/Instagram/IGListKit/pull/51)
- Added support for cells created from nibs. [Sven Bacia](https://github.com/svenbacia) [(#56)](https://github.com/Instagram/IGListKit/pull/56)
- Added an additional initializer for `IGListSingleSectionController` to be able to support single sections created from nibs. An example can be found [here](Example/IGListKitExamples/ViewControllers/SingleSectionViewController.swift).
- Fixed `-[IGListAdapter reloadDataWithCompletion:]` not returning early when `collectionView` or `dataSource` is nil and `completion` is nil. [Ben Asher](https://github.com/benasher44) [(#51)](https://github.com/Instagram/IGListKit/pull/51)
- Added `-isFirstSection` and `-isLastSection` APIs to `IGListSectionController`


1.0.0
-----

Expand Down
14 changes: 13 additions & 1 deletion Example/IGListKitExamples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
objects = {

/* Begin PBXBuildFile section */
26271C8E1DAE9D3F0073E116 /* SingleSectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26271C8D1DAE9D3F0073E116 /* SingleSectionViewController.swift */; };
26271C921DAE9EFC0073E116 /* NibCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 26271C911DAE9EFC0073E116 /* NibCell.xib */; };
26271C941DAE9F050073E116 /* NibCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26271C931DAE9F050073E116 /* NibCell.swift */; };
2942FF8C1D9F39E00015D24B /* DemoSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2942FF831D9F39E00015D24B /* DemoSectionController.swift */; };
2942FF8D1D9F39E00015D24B /* EmbeddedSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2942FF841D9F39E00015D24B /* EmbeddedSectionController.swift */; };
2942FF8E1D9F39E00015D24B /* ExpandableSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2942FF851D9F39E00015D24B /* ExpandableSectionController.swift */; };
Expand Down Expand Up @@ -37,6 +40,9 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
26271C8D1DAE9D3F0073E116 /* SingleSectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleSectionViewController.swift; sourceTree = "<group>"; };
26271C911DAE9EFC0073E116 /* NibCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NibCell.xib; sourceTree = "<group>"; };
26271C931DAE9F050073E116 /* NibCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibCell.swift; sourceTree = "<group>"; };
2942FF831D9F39E00015D24B /* DemoSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemoSectionController.swift; sourceTree = "<group>"; };
2942FF841D9F39E00015D24B /* EmbeddedSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmbeddedSectionController.swift; sourceTree = "<group>"; };
2942FF851D9F39E00015D24B /* ExpandableSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpandableSectionController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -148,6 +154,7 @@
299068271D75BFEC00A62888 /* MixedDataViewController.swift */,
2991F9231D7BB89F00B0C58F /* NestedAdapterViewController.swift */,
299B53FF1D6BD6630074A202 /* SearchViewController.swift */,
26271C8D1DAE9D3F0073E116 /* SingleSectionViewController.swift */,
);
path = ViewControllers;
sourceTree = "<group>";
Expand All @@ -162,6 +169,8 @@
2991F92B1D7BBE5400B0C58F /* RemoveCell.swift */,
2961B3AF1D68B28E001C9451 /* SearchCell.swift */,
2961B3A81D68B0B5001C9451 /* SpinnerCell.swift */,
26271C931DAE9F050073E116 /* NibCell.swift */,
26271C911DAE9EFC0073E116 /* NibCell.xib */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -247,6 +256,7 @@
buildActionMask = 2147483647;
files = (
2961B3981D68B031001C9451 /* LaunchScreen.storyboard in Resources */,
26271C921DAE9EFC0073E116 /* NibCell.xib in Resources */,
2961B3951D68B031001C9451 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -296,7 +306,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
Expand All @@ -314,6 +324,7 @@
2942FF931D9F39E00015D24B /* SearchSectionController.swift in Sources */,
2942FF911D9F39E00015D24B /* LabelSectionController.swift in Sources */,
2961B3AC1D68B0B5001C9451 /* LoadMoreViewController.swift in Sources */,
26271C941DAE9F050073E116 /* NibCell.swift in Sources */,
2991F9191D7BADC900B0C58F /* CenterLabelCell.swift in Sources */,
29628F141D91905A0026B15A /* DetailLabelCell.swift in Sources */,
2991F9301D7BC0E400B0C58F /* EmptyViewController.swift in Sources */,
Expand All @@ -326,6 +337,7 @@
2991F9281D7BB9EC00B0C58F /* EmbeddedCollectionViewCell.swift in Sources */,
2942FF8F1D9F39E00015D24B /* GridSectionController.swift in Sources */,
2942FF921D9F39E00015D24B /* RemoveSectionController.swift in Sources */,
26271C8E1DAE9D3F0073E116 /* SingleSectionViewController.swift in Sources */,
2961B3AD1D68B0B5001C9451 /* LabelCell.swift in Sources */,
2942FF901D9F39E00015D24B /* HorizontalSectionController.swift in Sources */,
2961B3AB1D68B0B5001C9451 /* DemosViewController.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class DemosViewController: UIViewController, IGListAdapterDataSource {
DemoItem(name: "Search Autocomplete", controllerClass: SearchViewController.self),
DemoItem(name: "Mixed Data", controllerClass: MixedDataViewController.self),
DemoItem(name: "Nested Adapter", controllerClass: NestedAdapterViewController.self),
DemoItem(name: "Empty View", controllerClass: EmptyViewController.self)
DemoItem(name: "Empty View", controllerClass: EmptyViewController.self),
DemoItem(name: "Single Section Controller", controllerClass: SingleSectionViewController.self)
]

override func viewDidLoad() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
The examples provided by Facebook are for non-commercial testing and evaluation
purposes only. Facebook reserves all rights not expressly granted.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import UIKit
import IGListKit

final class SingleSectionViewController: UIViewController, IGListAdapterDataSource, IGListSingleSectionControllerDelegate {

lazy var adapter: IGListAdapter = {
return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0)
}()

let collectionView = IGListCollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout())

var data = [Int]()

// MARK: - Lifecycle

override func viewDidLoad() {
super.viewDidLoad()

for index in 0..<20 {
data.append(index)
}

view.addSubview(collectionView)
adapter.collectionView = collectionView
adapter.dataSource = self
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.frame = view.bounds
}

//MARK: - IGListAdapterDataSource

func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] {
return data as [IGListDiffable]
}

func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController {
let configureBlock = { (data: Any, cell: UICollectionViewCell) in
guard let cell = cell as? NibCell, let number = data as? Int else { return }
cell.textLabel.text = "Cell: \(number + 1)"
}

let sizeBlock = { (context: IGListCollectionContext) -> CGSize in
return CGSize(width: context.containerSize.width, height: 44)
}
let sectionController = IGListSingleSectionController(nibName: NibCell.nibName,
bundle: nil,
configureBlock: configureBlock,
sizeBlock: sizeBlock)
sectionController.selectionDelegate = self

return sectionController
}

func emptyView(for listAdapter: IGListAdapter) -> UIView? {
return nil
}

// MARK: - IGListSingleSectionControllerDelegate

func didSelect(_ sectionController: IGListSingleSectionController) {
let section = adapter.section(for: sectionController) + 1
let alert = UIAlertController(title: "Section \(section) was selected 🎉", message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}

}
22 changes: 22 additions & 0 deletions Example/IGListKitExamples/Views/NibCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
The examples provided by Facebook are for non-commercial testing and evaluation
purposes only. Facebook reserves all rights not expressly granted.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import UIKit

final class NibCell: UICollectionViewCell {
static let nibName = "NibCell"
@IBOutlet var textLabel: UILabel!
}


52 changes: 52 additions & 0 deletions Example/IGListKitExamples/Views/NibCell.xib
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="Bsi-Xi-IXl" customClass="NibCell" customModule="IGListKitExamples" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="626" height="116"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="626" height="116"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KmO-E2-9FY" userLabel="Separator">
<color key="backgroundColor" white="0.94999999999999996" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="DGO-9u-efg"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fAB-2v-237">
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="🎉" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qTT-Ka-LDD">
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
<constraints>
<constraint firstItem="KmO-E2-9FY" firstAttribute="trailing" secondItem="qTT-Ka-LDD" secondAttribute="trailing" id="BRa-QC-qg0"/>
<constraint firstAttribute="bottom" secondItem="KmO-E2-9FY" secondAttribute="bottom" id="Uac-CQ-cJ8"/>
<constraint firstItem="qTT-Ka-LDD" firstAttribute="centerY" secondItem="fAB-2v-237" secondAttribute="centerY" id="VFC-J9-qNd"/>
<constraint firstItem="KmO-E2-9FY" firstAttribute="leading" secondItem="fAB-2v-237" secondAttribute="leading" id="WqJ-nx-XeD"/>
<constraint firstAttribute="trailing" secondItem="qTT-Ka-LDD" secondAttribute="trailing" constant="15" id="XaH-vp-MoX"/>
<constraint firstItem="fAB-2v-237" firstAttribute="leading" secondItem="Bsi-Xi-IXl" secondAttribute="leading" constant="15" id="h0E-pO-BbL"/>
<constraint firstItem="fAB-2v-237" firstAttribute="centerY" secondItem="Bsi-Xi-IXl" secondAttribute="centerY" id="oqm-jR-6tv"/>
</constraints>
<size key="customSize" width="626" height="116"/>
<connections>
<outlet property="textLabel" destination="fAB-2v-237" id="0k5-X7-Ifn"/>
</connections>
<point key="canvasLocation" x="164" y="-249"/>
</collectionViewCell>
</objects>
</document>
4 changes: 3 additions & 1 deletion Example/IGListKitExamples/Views/SpinnerCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ func spinnerSectionController() -> IGListSingleSectionController {
let sizeBlock = { (context: IGListCollectionContext) -> CGSize in
return CGSize(width: context.containerSize.width, height: 100)
}
return IGListSingleSectionController(cellClass: SpinnerCell.self, configureBlock: configureBlock, sizeBlock: sizeBlock)
return IGListSingleSectionController(cellClass: SpinnerCell.self,
configureBlock: configureBlock,
sizeBlock: sizeBlock)
}

class SpinnerCell: UICollectionViewCell {
Expand Down
6 changes: 3 additions & 3 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PODS:
- IGListKit (1.0)
- IGListKit (1.0.0)

DEPENDENCIES:
- IGListKit (from `../IGListKit.podspec`)
Expand All @@ -9,8 +9,8 @@ EXTERNAL SOURCES:
:path: ../IGListKit.podspec

SPEC CHECKSUMS:
IGListKit: 67493f1f775fea949596c7fc8317c7bd77ba8539
IGListKit: 3242c475fa77e2abf2d4de319703088008fbe9b9

PODFILE CHECKSUM: 4bdfb42d1e7b2b121bf8c83bc300d7d77aa0fc3a

COCOAPODS: 1.0.1
COCOAPODS: 1.1.0.rc.3
9 changes: 5 additions & 4 deletions Example/Pods/Local Podspecs/IGListKit.podspec.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Example/Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ce4b851

Please sign in to comment.