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

[Unexpacted ConstrainedSize Apply issue] Automatically setNeedsLayout before ASCellNode didLoad #10

Open
GeekTree0101 opened this issue Jul 25, 2018 · 1 comment

Comments

@GeekTree0101
Copy link
Owner

ASDisplayNode+UIViewBridge.mm

ASBinder setNeedsLayout sometime called before ASCellNode loaded

- (void)layoutIfNeeded
{
  BOOL shouldApply = NO;
  BOOL loaded = NO;
  id viewOrLayer = nil;
  {
    _bridge_prologue_write;
    shouldApply = ASDisplayNodeShouldApplyBridgedWriteToView(self);
    loaded = __loaded(self);
    viewOrLayer = _view ?: _layer;
    if (shouldApply == NO && loaded) {
      // The node is loaded but we're not on main.
      // We will call layoutIfNeeded on the view or layer when we apply the pending state. __layout will in turn be called on us (see -[_ASDisplayLayer layoutSublayers]).
      // We need to call it on main if the node is loaded to support automatic subnode management.
      // We can't release the lock before applying to pending state, or it may be flushed before it can be applied.
      [ASDisplayNodeGetPendingState(self) layoutIfNeeded];
    }
  }
  
  if (shouldApply) {
    // The node is loaded and we're on main.
    // Message the view or layer which in turn will call __layout on us (see -[_ASDisplayLayer layoutSublayers]).
    [viewOrLayer layoutIfNeeded];
  } else if (loaded == NO) {
    // The node is not loaded and we're not on main.
    [self __layout];
  }
}

In this case, ASCellNode constrainedSize can't change no more

@GeekTree0101
Copy link
Owner Author

Will support this code

extension Reactive where Base: ASDisplayNode {
    
    var didLoad: ControlEvent<Void> {
        let source = self.methodInvoked(#selector(Base.didLoad)).map { _ in return }
        return ControlEvent(events: source)
    }
}

extension Observable {
    func onDidLoad(_ node: ASDisplayNode) -> Observable<Element> {
        return self.withLatestFrom(node.rx.didLoad) { ($0, $1) }
            .map { $0.0 }
            .asObservable()
    }
}

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

No branches or pull requests

1 participant