Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

[ASViewController] Support optional node #3021

Merged
merged 5 commits into from
Feb 14, 2017
Merged

[ASViewController] Support optional node #3021

merged 5 commits into from
Feb 14, 2017

Conversation

maicki
Copy link
Contributor

@maicki maicki commented Feb 13, 2017

Thanks to @nguyenhuy for the initial work! Unfortunately there were a couple of bigger changes since the last commit of the initial PR so I rebased and also cleaned it up a bit. Will replace #2810

This PR makes ASViewController's node optional. This allows developers to use ASViewController like a normal UIViewController. More importantly, it can be used as a base class for view controllers among which some use a node hierarchy and some don't.

Resolve #2760.

nguyenhuy and others added 4 commits February 12, 2017 18:15
- If a node isn't provided by developers via -initWithNode:, a default one will be created and used internally.
- This allows developers to use ASViewController like a normal UIViewController and as a base class for all view controllers among which some use a node hierarchy and some don't.
- If its node isn't provided by users, don't replace the view controller's view with the default node's view because it might be loaded from a nib.
- Init a vanilla ASDisplayNode if a node isn't provided.
Copy link
Contributor

@nguyenhuy nguyenhuy left a comment

Choose a reason for hiding this comment

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

@maicki Thanks so much for the rebase and clean up.

Copy link
Contributor

@Adlai-Holler Adlai-Holler left a comment

Choose a reason for hiding this comment

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

I'm not completely sold on this change, at least as-implemented. Let me know what you think about those comments and we can talk from there.

*
* @param node An ASDisplayNode which will provide the root view (self.view)
* @return An ASViewController instance whose root view will be backed by the provided ASDisplayNode.
*
* @see ASVisibilityDepth
*/
- (instancetype)initWithNode:(DisplayNodeType)node NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithNode:(DisplayNodeType)node;

/**
* @return node Returns the ASDisplayNode which provides the backing view to the view controller.
Copy link
Contributor

Choose a reason for hiding this comment

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

We should mark the _node property nullable instead of using a dummy node. This will be breaking API for Swift, but it's cleaner and avoids the need for _providedNode.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sold on having a nil node within the view controller. If we would go ahead with that, we always would have to check for if the node is nil on every call within ASViewController and also all subclasses need to consider that (Swift needs to unwrap). I know you can call methods on nil within Objective-C ...

We will have an overhead with having around a temporary node that's true ...

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not concerned with overhead – it's simply incorrect to have a node around that you never touch or add to the window hierarchy (because we wrap it in this _didProvideNode flag). That's not any safer than having a nil node.

if (!_nodeProvided) { return; }

ASDisplayNodeAssertTrue(!_node.layerBacked);

UIView *view = self.view;
CGRect frame = view.frame;
UIViewAutoresizing autoresizingMask = view.autoresizingMask;
Copy link
Contributor

Choose a reason for hiding this comment

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

So if you call -setNode: after the view is loaded, won't we be in chaos? self.node will get updated, but the node won't get hosted in the view hierarchy.

Copy link
Contributor Author

@maicki maicki Feb 14, 2017

Choose a reason for hiding this comment

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

The node property is currently declared as readonly. It should be not possible to set a node after a view controller is initialized.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah OK I had assumed this diff made it readwrite to appease the community members who wanted to use nodes but didn't want to use initWithNode:. Cool.

Copy link
Contributor

@Adlai-Holler Adlai-Holler left a comment

Choose a reason for hiding this comment

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

(Mirrored from our discussion on Slack) The move here is to use an implicitly-unwrapped optional for the node property. If they don't give us one, it's nil. If they unwrap let node: ASDisplayNode = vc.node in Swift (if they assume an ASViewController has a node) they get a crash. These crashes should be pretty easy to debug, and very easy to prevent (guard let node = vc.node else { assertionFailure("Expected vc to have a node"); return ; }).

This way everyone can tell whether an ASViewController has a node or not, but Swift users won't have to constantly unwrap their node properties manually.

@maicki
Copy link
Contributor Author

maicki commented Feb 14, 2017

Pushed a new change that changes the nil node behavior based on @Adlai-Holler and my Slack conversation.

It also changes the usage of mixed between the getter self.node and the instance variable _node to always use the intense variable for now.

@garrettmoon garrettmoon added this to the 2.2 milestone Feb 14, 2017
Copy link
Contributor

@Adlai-Holler Adlai-Holler left a comment

Choose a reason for hiding this comment

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

Cool

@maicki
Copy link
Contributor Author

maicki commented Feb 14, 2017

Thanks @Adlai-Holler and @nguyenhuy for working together on that.

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

Successfully merging this pull request may close these issues.

None yet

5 participants