diff --git a/YogaKit/Source/UIView+Yoga.h b/YogaKit/Source/UIView+Yoga.h index 092c9dcd..4272ecd1 100644 --- a/YogaKit/Source/UIView+Yoga.h +++ b/YogaKit/Source/UIView+Yoga.h @@ -10,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN typedef void (^YGLayoutConfigurationBlock)(YGLayout *layout); +typedef void (^YGLayoutContainerConfigurationBlock)(YGLayout *layout, UIView *container); @interface UIView (Yoga) @@ -30,6 +31,14 @@ typedef void (^YGLayoutConfigurationBlock)(YGLayout *layout); - (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block NS_SWIFT_NAME(configureLayout(block:)); +/** + In ObjC land, every time you access `view.yoga.*` you are adding another `objc_msgSend` + to your code. If you plan on making multiple changes to YGLayout, it's more performant + to use this method, which uses a single objc_msgSend call. + */ +- (void)configureLayoutWithContainerBlock:(YGLayoutContainerConfigurationBlock)block + NS_SWIFT_NAME(configureLayout(containerBlock:)); + @end NS_ASSUME_NONNULL_END diff --git a/YogaKit/Source/UIView+Yoga.m b/YogaKit/Source/UIView+Yoga.m index b67e63cb..fd3b3909 100644 --- a/YogaKit/Source/UIView+Yoga.m +++ b/YogaKit/Source/UIView+Yoga.m @@ -35,4 +35,11 @@ static const void *kYGYogaAssociatedKey = &kYGYogaAssociatedKey; } } +- (void)configureLayoutWithContainerBlock:(YGLayoutContainerConfigurationBlock)block +{ + if (block != nil) { + block(self.yoga, self); + } +} + @end diff --git a/YogaKit/Tests/YogaKitTests.m b/YogaKit/Tests/YogaKitTests.m index 13f0d314..a928bb60 100644 --- a/YogaKit/Tests/YogaKitTests.m +++ b/YogaKit/Tests/YogaKitTests.m @@ -22,6 +22,13 @@ XCTAssertNoThrow([view configureLayoutWithBlock:block]); } +- (void)testConfigureContainerLayoutIsNoOpWithNilBlock +{ + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + id block = nil; + XCTAssertNoThrow([view configureLayoutWithContainerBlock:block]); +} + - (void)testConfigureLayoutBlockWorksWithValidBlock { UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; @@ -35,6 +42,20 @@ XCTAssertEqual(view.yoga.width.value, 25); } +- (void)testConfigureContainerLayoutBlockWorksWithValidBlock +{ + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + [view configureLayoutWithContainerBlock:^(YGLayout *layout, UIView *container){ + XCTAssertNotNil(layout); + XCTAssertTrue(view == container); + layout.isEnabled = YES; + layout.width = YGPointValue(25); + }]; + + XCTAssertTrue(view.yoga.isEnabled); + XCTAssertEqual(view.yoga.width.value, 25); +} + - (void)testNodesAreDeallocedWithSingleView { __weak YGLayout *layoutRef = nil;