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

[ASCornerLayoutSpec] New layout spec class for declarative corner element layout. #657

Merged
merged 7 commits into from
Nov 24, 2017

Conversation

huang-kun
Copy link
Contributor

This PR includes implementation code, snapshot test and examples (both objc and swift).

@huang-kun
Copy link
Contributor Author

This PR comes from #623. I will start one commit here instead of a whole mass. Make it easy for code review and CI build.

@huang-kun huang-kun changed the title [ASCornerLayoutSpec] new layout spec class for declarative corner element layout. [ASCornerLayoutSpec] New layout spec class for declarative corner element layout. Nov 3, 2017
Copy link
Member

@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.

Thanks for working on this. There are a few things we should address before merging.

On a separate note, and definitely not a blocker for this PR, but it would be great if we can update the README file in Examples dir to include some screenshots of your additions. That would help people to quickly understand your new spec and nodes without running the sample.

@property (nonatomic, assign) CGPoint offset;

/**
Should include corner element into layout size calculation. If included, the layout size will be the union size of both child and corner; If not included, the layout size will be only child's size. Default is NO.
Copy link
Member

Choose a reason for hiding this comment

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

Nit: This line is too long. Please split it into multiple ones, maximum 120 chars each. Same for some other lines each this file.

/**
Should include corner element into layout size calculation. If included, the layout size will be the union size of both child and corner; If not included, the layout size will be only child's size. Default is NO.
*/
@property (nonatomic, assign) BOOL includeCornerForSizeCalculation;
Copy link
Member

Choose a reason for hiding this comment

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

How about wrapsCorner?


NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, ASCornerLayoutLocation) {
Copy link
Member

Choose a reason for hiding this comment

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

Coding convention: Method, @interface, and @implementation brackets on the following line.

Please also update the rest of this diff to follow the convention.

CGSize size = element.style.preferredSize;
if (!CGSizeEqualToSize(size, CGSizeZero) && !ASIsCGSizeValidForSize(size) && (size.width < 0 || (size.height < 0))) {
NSString *failedReason = [NSString stringWithFormat:@"[%@]: Should give a valid preferredSize value for %@ before corner's position calculation.", self.class, element];
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:failedReason userInfo:nil];
Copy link
Member

Choose a reason for hiding this comment

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

Let's be lenient by triggering assertions instead of throwing exceptions in development, and fall back to a default size/layout in production. What do you think?

[self validateElement:corner];

// Layout child
ASLayout *childLayout = [child layoutThatFits:constrainedSize parentSize:constrainedSize.max];
Copy link
Member

Choose a reason for hiding this comment

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

When the constrained size range has an infinite max size, the parent size needs to be adjusted. Please either override calculateLayoutThatFits:restrictedToSize:relativeToParentSize:, or adjust the size like this.


// Update corner's position
cornerLayout.position = relativePosition;
corner.style.layoutPosition = relativePosition;
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is needed.

CGRect frame = childLayout.frame;
if (_includeCornerForSizeCalculation) {
frame = CGRectUnion(childLayout.frame, cornerLayout.frame);
frame.size = ASSizeRangeClamp(constrainedSize, frame.size);
Copy link
Member

Choose a reason for hiding this comment

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

Yes, always clamp against the constrained size range 👍


- (void)testCornerSpecWithLocation:(ASCornerLayoutLocation)location
offsetOption:(ASCornerLayoutSpecSnapshotTestsOffsetOption)offsetOption
childSizeOnly:(BOOL)childSizeOnly {
Copy link
Member

Choose a reason for hiding this comment

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

Let's use the same name that the corner spec uses (includeCornerForSizeCalculation or wrapsCorner depends on its final name).

private func circularize(_ node: ASDisplayNode, in size: CGSize) {
assert(size.width == size.height)
node.style.preferredSize = size
node.cornerRadius = size.width / 2
Copy link
Member

Choose a reason for hiding this comment

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

Not a blocker and don't spend too much time on this, but please consider other rounding techniques mentioned here, if possible. I'm not concerned about the performance in this sample application, but rather using best practices in example code.

_badgeNode = [ASTextNode new];
_badgeNode.attributedText = numberText;
_badgeNode.backgroundColor = UIColor.redColor;
_badgeNode.cornerRadius = 12;
Copy link
Member

Choose a reason for hiding this comment

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

Same here and below, let's avoid cornerRadius whenever makes sense.

Copy link
Member

@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.

I can't be happier to hit the approve button! Thank you for not only putting up a new layout spec but also taking care of tests and examples. Way to go for all of us!

#import <AsyncDisplayKit/ASLayoutSpec+Subclasses.h>
#import <AsyncDisplayKit/ASDisplayNode.h>

CGPoint as_calculatedCornerOriginIn(CGRect baseFrame, CGSize cornerSize, ASCornerLayoutLocation cornerLocation, CGPoint offset) {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: open curly bracket in a new line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for refining so much details on the new layout spec. I kept the curly bracket at the end of function as the code guide line declared. 🤔🤔🤔 It says:

  • Function brackets on the same line
static void someFunction() {
  // Implementation
}


@implementation ASCornerLayoutSpecSnapshotTests

- (void)setUp {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: method curly brackets in new lines throughout this file.


#pragma mark - Calculation

- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
Copy link
Member

Choose a reason for hiding this comment

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

This whole layout algorithm is a beauty!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great to hear that 😁

Copy link
Contributor

@maicki maicki left a comment

Choose a reason for hiding this comment

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

@huang-kun Thank you, pretty great work on the ASCornerLayoutSpec!

@TextureGroup TextureGroup deleted a comment Nov 23, 2017
@nguyenhuy
Copy link
Member

Here we go. Thanks again!

@nguyenhuy nguyenhuy merged commit e4b2c05 into TextureGroup:master Nov 24, 2017
@huang-kun
Copy link
Contributor Author

Would you like me to introduce the ASCornerLayoutSpec into your official doc at here after new version release? @nguyenhuy @maicki

@nguyenhuy
Copy link
Member

nguyenhuy commented Nov 25, 2017 via email

bernieperez pushed a commit to AtomTickets/Texture that referenced this pull request Apr 25, 2018
…ment layout. (TextureGroup#657)

* Add new layout spec class with snapshot testing. Update examples and CHANGELOG.md

* Code review updates.

* Open curly bracket in a new line.
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

Successfully merging this pull request may close these issues.

3 participants