Skip to content

Commit

Permalink
[ASDisplayNode layout] Fix an issue that sometimes causes a node's pe…
Browse files Browse the repository at this point in the history
…nding layout to not be applied (TextureGroup#792)

* [ASDisplayNode layout] Fix an issue that causes a node's pending layout to not be applied

- Since the implementation of layout version (TextureGroup#428), if a node's pending and calculated layouts have the same current version as well as the same constrained size, the 2 layouts are considered equal and can be used interchangeably. A layout version check between the 2 layouts was added in TextureGroup#695. This PR adds a missing constrained size check.
- If the pending layout has the same version but a different constrained size compare to the calculated layout's, we can assume that the pending layout is newer and should be preferred over the calculated one. That is because layout operations always register their new layout as pending, which then (immediately or eventually) get applied to the node as calculated layout.
  • Loading branch information
nguyenhuy authored and bernieperez committed Apr 25, 2018
1 parent 63c81ee commit c414ef4
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
- [ASNetworkImageNode] Deprecates .URLs in favor of .URL [Garrett Moon](https://github.com/garrettmoon) [#699](https://github.com/TextureGroup/Texture/pull/699)
- [iOS11] Update project settings and fix errors [Eke](https://github.com/Eke) [#676](https://github.com/TextureGroup/Texture/pull/676)
- [ASCornerLayoutSpec] New layout spec class for declarative corner element layout. [#657](https://github.com/TextureGroup/Texture/pull/657) [huangkun](https://github.com/huang-kun)
- [Layout] Fix an issue that causes a pending layout to be applied multiple times. [Huy Nguyen](https://github.com/nguyenhuy) [#695](https://github.com/TextureGroup/Texture/pull/695)
- [ASDisplayNode layout] Fix an issue that causes a pending layout to be applied multiple times. [Huy Nguyen](https://github.com/nguyenhuy) [#695](https://github.com/TextureGroup/Texture/pull/695)
- [ASDisplayNode layout] Fix an issue that sometimes causes a node's pending layout to not be applied. [Huy Nguyen](https://github.com/nguyenhuy) [#792](https://github.com/TextureGroup/Texture/pull/792)
- [ASScrollNode] Ensure the node respects the given size range while calculating its layout. [#637](https://github.com/TextureGroup/Texture/pull/637) [Huy Nguyen](https://github.com/nguyenhuy)
- [ASScrollNode] Invalidate the node's calculated layout if its scrollable directions changed. Also add unit tests for the class. [#637](https://github.com/TextureGroup/Texture/pull/637) [Huy Nguyen](https://github.com/nguyenhuy)
- Add new unit testing to the layout engine. [Adlai Holler](https://github.com/Adlai-Holler) [#424](https://github.com/TextureGroup/Texture/pull/424)
Expand Down
28 changes: 22 additions & 6 deletions Source/ASDisplayNode+Layout.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
// ASDisplayNode+Layout.mm
// Texture
//
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional
// grant of patent rights can be found in the PATENTS file in the same directory.
//
// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present,
// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
Expand Down Expand Up @@ -300,13 +305,24 @@ - (void)_u_measureNodeWithBoundsIfNecessary:(CGRect)bounds
}

CGSize boundsSizeForLayout = ASCeilSizeValues(bounds.size);
NSUInteger calculatedVersion = _calculatedDisplayNodeLayout->version;

// Prefer a newer and not yet applied _pendingDisplayNodeLayout over _calculatedDisplayNodeLayout
// If there is no such _pending, check if _calculated is valid to reuse (avoiding recalculation below).
BOOL pendingLayoutIsPreferred = (_pendingDisplayNodeLayout != nullptr
&& _pendingDisplayNodeLayout->version >= _layoutVersion
&& _pendingDisplayNodeLayout->version > _calculatedDisplayNodeLayout->version); // _pending is not yet applied
BOOL calculatedLayoutIsReusable = (_calculatedDisplayNodeLayout->version >= _layoutVersion
BOOL pendingLayoutIsPreferred = NO;
if (_pendingDisplayNodeLayout != nullptr) {
NSUInteger pendingVersion = _pendingDisplayNodeLayout->version;
if (pendingVersion >= _layoutVersion) {
if (pendingVersion > calculatedVersion) {
pendingLayoutIsPreferred = YES; // Newer _pending
} else if (pendingVersion == calculatedVersion
&& !ASSizeRangeEqualToSizeRange(_pendingDisplayNodeLayout->constrainedSize,
_calculatedDisplayNodeLayout->constrainedSize)) {
pendingLayoutIsPreferred = YES; // _pending with a different constrained size
}
}
}
BOOL calculatedLayoutIsReusable = (calculatedVersion >= _layoutVersion
&& (_calculatedDisplayNodeLayout->requestedLayoutFromAbove
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout->layout.size, boundsSizeForLayout)));
if (!pendingLayoutIsPreferred && calculatedLayoutIsReusable) {
Expand Down

0 comments on commit c414ef4

Please sign in to comment.