Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support cells created from nibs #56

Closed
wants to merge 1 commit into from
Closed

Support cells created from nibs #56

wants to merge 1 commit into from

Conversation

svenbacia
Copy link
Contributor

@svenbacia svenbacia commented Oct 12, 2016

Changes in this pull request

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.

Missing

Pull request checklist

  • All tests pass. Demo project builds and runs.
  • I added tests, an experiment, or detailed why my change isn't tested.
  • I have reviewed the contributing guide

@facebook-github-bot
Copy link
Contributor

Thank you for your pull request. As you may know, we require contributors to sign our Contributor License Agreement, and we don't seem to have you on file and listed as active anymore. In order for us to review and merge your code, please email cla@fb.com with your details so we can update your status.

@facebook-github-bot
Copy link
Contributor

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks!

cellClass:(Class)cellClass
forSectionController:(IGListSectionController<IGListSectionType> *)sectionController
atIndex:(NSInteger)index
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Can you put the curly on the same line?

@note This method uses a string representation of the cell class as the identifier.
*/
- (__kindof UICollectionViewCell *)dequeueReusableCellFromNibName:(NSString *)nibName
bundle:(NSBundle * _Nullable)bundle
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we've been using the format (nullable NSBundle *) elsewhere in the app

bundle:(NSBundle * _Nullable)bundle
cellClass:(Class)cellClass
configureBlock:(IGListSingleSectionCellConfigureBlock)configureBlock
sizeBlock:(IGListSingleSectionCellSizeBlock)sizeBlock;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @jessesquires on adding another initializer. I prefer having a single init, but that'll mean a breaking change.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's early yet, I think we should not be afraid of a few breaking changes to start with?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, let's break it. @svenbacia mind changing this so there's only a single init? Note that this will break the sample apps and unit tests, but chasing the compiler errors should be easy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another option:

we could have 2 initializers for a 1.1.0 non-breaking release. then, open a task to track combining these into 1 initializer for a 2.0.0 (breaking) release.

(usually "self") or the IGListAdapter. Pass in locally scoped objects or use weak references!
*/
- (instancetype)initWithNibName:(NSString *)nibName
bundle:(NSBundle * _Nullable)bundle
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nullable NSBundle *)

@@ -18,8 +18,8 @@
NS_ASSUME_NONNULL_BEGIN

/// Generate a string representation of a reusable view class when registering with a UICollectionView.
NS_INLINE NSString *IGListReusableViewIdentifier(Class viewClass, NSString * _Nullable kind) {
return [NSString stringWithFormat:@"%@%@", kind ?: @"", NSStringFromClass(viewClass)];
NS_INLINE NSString *IGListReusableViewIdentifier(Class viewClass, NSString * _Nullable nibName, NSString * _Nullable kind) {
Copy link
Contributor

@rnystrom rnystrom Oct 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nullable NSString * x2

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: nullable isn't available in C functions :)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bikeshed: what's the thinking on why this should be inline and header-defined? Any possible computational speed benefits are nullified by the first msgSend you do inside the function body.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kylehickinson TIL, maybe we should change all of them to _Nullable then so we're consistent.... sounds like another good starter-task.

@ocrickard We could extern it, but its exposed in the internal header for unit testing in IGListAdapterTests.m

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rnystrom

maybe we should change all of them to _Nullable

Eh, I don't think so. nullable is preferred for ObjC contexts, _Nullable is preferred for C contexts

@rnystrom
Copy link
Contributor

rnystrom commented Oct 12, 2016

This is really, really great. I know the community is going to want this feature ASAP. Aside from my notes on the review, a couple other things we need to do:

  • Gen the documentation (jazzy is sort of broken w/ the dir structure, see Error when running ./build_docs.sh #55 for a temp workaround)
  • Add unit tests
    • Add a test nib as a resource to the tests target
    • Unit test using cells (test that they are created and configured)
    • Unit test the single item controller (which I totally didn't think about!)
  • Optional: Add an example to the samples app
    • This could be something really simple, but maybe a cell w/ some autolayout labels or w/e
  • Add a line to the changelog
    • Since we don't have any examples, take a look at @jessesquires's CHANGELOG for an idea of the format/content

@facebook-github-bot
Copy link
Contributor

@svenbacia updated the pull request - view changes

@jessesquires
Copy link
Contributor

Gen the documentation

I'd personally prefer this in a separate PR. We should do this right before we push a new release with these changes. Otherwise, our docs and code are inconsistent. (That is, most people will be using CocoaPods/Carthage, pinned to a release tag, not using master. I think published docs should be for a release, not for master.)

@rnystrom
Copy link
Contributor

@jessesquires interesting, I'm down w/ that workflow. I should detail that in the contributing docs. Should we revert it here?

@jessesquires
Copy link
Contributor

Up to you.

I probably would, but this is also a minor change -- and it looks like we're going to push 2.0.0 out soon? (like probably this week or next?)

@facebook-github-bot
Copy link
Contributor

@svenbacia updated the pull request - view changes

@svenbacia
Copy link
Contributor Author

Thanks for the feedback. I think I covered all open points. Please let me know in case there are still something missing/wrong.

@@ -2,6 +2,17 @@

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

x.y.z
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will be 2.0.0

@facebook-github-bot
Copy link
Contributor

@svenbacia updated the pull request - view changes

-----
### Breaking Changes

- Extended the initializer for `IGListSingleSectionController` to be able to support single sections created from nibs. Therefore the initializer now takes two new arguments `nibName` and `bundle`. An example can be found [here](Example/IGListKitExamples/ViewControllers/SingleSectionViewController.swift).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌

data.append(index)
}

collectionView.backgroundColor = .white
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this, IGListCollectionView sets the background to white by default

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

let rowCount = 20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Let's remove this variable and just do for index in 0..<20 below, simpler


func didSelect(_ sectionController: IGListSingleSectionController) {
let section = adapter.section(for: sectionController) + 1
let alert = UIAlertController(title: "Section \(section) was selected 🎉", message: nil, preferredStyle: .alert)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this!

NSIndexPath *indexPath = [self indexPathForSectionController:sectionController index:index];
if (![self.registeredCellClasses containsObject:cellClass]) {
[self.registeredCellClasses addObject:cellClass];
UINib *nib = [UINib nibWithNibName:nibName bundle:bundle];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noting to myself that we don't need an assert to check if the nib exists b/c according to the docs:

An exception is thrown if there were errors during initialization or the nib file could not be located.

Dequeues a cell from the UICollectionView reuse pool.

@param nibName The name of the nib file.
@param bundle The bundle in which to search for the nib file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Add what happens when this is nil:

If nil, this method looks for the nib file in the main bundle.

*/
- (__kindof UICollectionViewCell *)dequeueReusableCellFromNibName:(NSString *)nibName
bundle:(nullable NSBundle *)bundle
cellClass:(Class)cellClass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we omit this parameter? I know you're using it to lookup registration in the registeredCellClasses and create the cell identifier, but we could:

  • Add another registered set NSMutableSet<NSString *> *registeredNibNames
  • Use the nib name string to lookup if the nib has been registered
  • Use the nib name string as the cell identifier

That'd reduce the complexity and number of parameters for this method, making a simpler API. What do you think? cc @jessesquires

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. Given that we are returning a UICollectionViewCell in either case we don't actually need the class 👍

Copy link
Contributor Author

@svenbacia svenbacia Oct 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started implementing this and I realized that the initializer for IGListSingleSectionController now has 3 nullable parameters since we no longer need the cellClass for nib cells. Is this too confusing for the user? Maybe we should split the initializer.

- (instancetype)initWithCellClass:(nullable Class)cellClass
                          nibName:(nullable NSString *)nibName
                           bundle:(nullable NSBundle *)bundle
                   configureBlock:(IGListSingleSectionCellConfigureBlock)configureBlock
                        sizeBlock:(IGListSingleSectionCellSizeBlock)sizeBlock NS_DESIGNATED_INITIALIZER;

@rnystrom
Copy link
Contributor

Making really great progress on this. This and storyboard support are easily the most wanted features right now. Going to make a lot of people happy!

@facebook-github-bot
Copy link
Contributor

@svenbacia updated the pull request - view changes

@facebook-github-bot
Copy link
Contributor

@svenbacia updated the pull request - view changes

@rnystrom
Copy link
Contributor

rnystrom commented Oct 14, 2016

Awesome!! @svenbacia last couple things then I think we're g2g:

  • Looks like it needs a rebase to fix the conflicts in CHANGELOG.md
  • Can you squash all the commits into a single commit?

edit: nvm that last one, I'll try to import as-is and see what happens

@svenbacia
Copy link
Contributor Author

Great! Let me know in case you need all commits in a single one.

@svenbacia
Copy link
Contributor Author

I just realized that due to the latest changes to the IGListSingleSectionController there are no breaking changes. I will update the CHANGELOG.

@facebook-github-bot
Copy link
Contributor

@svenbacia updated the pull request - view changes

2.0.0
-----

### Enhancements
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rebase and put this all under "Master"? I'm going to change the version in another diff

@facebook-github-bot
Copy link
Contributor

@svenbacia updated the pull request - view changes

@svenbacia
Copy link
Contributor Author

First time I used rebase. I hope this is what you expected. At least the conflict is gone.

@rnystrom
Copy link
Contributor

@svenbacia last request (I promise) is to revert the changes to docs/*. I'm going to run the script in a separate diff.

Rebase looks like it worked!

@facebook-github-bot
Copy link
Contributor

@svenbacia updated the pull request - view changes

@svenbacia
Copy link
Contributor Author

@rnystrom Done :)

@facebook-github-bot
Copy link
Contributor

Thanks for importing. If you are a Facebook employee, you can view this diff on Phabricator.

@rnystrom
Copy link
Contributor

Import is landing! 💪

I made a couple changes off of @dshahidehpour's internal review. You can check them out once the commit is pushed, but notably:

  • Renamed method from dequeueReusableCellFromNibName: to dequeueReusableCellWithNibName:
  • Changelog version to 1.1.0
  • Checking string length instead of nil string
  • Store property used twice in method in a local var

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants