diff --git a/YogaKit/CHANGELOG.md b/YogaKit/CHANGELOG.md index 49c46f2f..58f41d9b 100644 --- a/YogaKit/CHANGELOG.md +++ b/YogaKit/CHANGELOG.md @@ -25,3 +25,20 @@ view.yoga.marginLeft // 0 ### Enhancements - Pixel Rounding now uses `roundf()` instead of `round()`. + +- There is now a method that allows "bulk" updates to YGLayout. +```objc +[view configureLayoutWithBlock:^(YGLayout *layout) { + layout.isEnabled = YES; + layout.width = 50; + layout.height = 50; +}]; +``` + +```swift +view.configureLayout { (layout) in + layout.isEnabled = true + layout.width = 50 + layout.height = 50 +} +``` diff --git a/YogaKit/Source/UIView+Yoga.h b/YogaKit/Source/UIView+Yoga.h index 1af3581b..e75119c0 100644 --- a/YogaKit/Source/UIView+Yoga.h +++ b/YogaKit/Source/UIView+Yoga.h @@ -10,8 +10,24 @@ #import "YGLayout.h" #import +NS_ASSUME_NONNULL_BEGIN + +typedef void (^YGLayoutConfigurationBlock)(YGLayout *); + @interface UIView (Yoga) +/** + The YGLayout that is attached to this view. It is lazily created. + */ @property (nonatomic, readonly, strong) YGLayout *yoga; +/** + 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)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block NS_SWIFT_NAME(configureLayout(block:)); + @end + +NS_ASSUME_NONNULL_END diff --git a/YogaKit/Source/UIView+Yoga.m b/YogaKit/Source/UIView+Yoga.m index 66b7eed0..4448b377 100644 --- a/YogaKit/Source/UIView+Yoga.m +++ b/YogaKit/Source/UIView+Yoga.m @@ -26,5 +26,11 @@ static const void *kYGYogaAssociatedKey = &kYGYogaAssociatedKey; return yoga; } +- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block +{ + if (block != nil) { + block(self.yoga); + } +} @end diff --git a/YogaKit/Tests/YogaKitTests.m b/YogaKit/Tests/YogaKitTests.m index dcb089e8..5a1d56f1 100644 --- a/YogaKit/Tests/YogaKitTests.m +++ b/YogaKit/Tests/YogaKitTests.m @@ -18,6 +18,25 @@ @implementation YogaKitTests +- (void)testConfigureLayoutIsNoOpWithNilBlock +{ + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + XCTAssertNoThrow([view configureLayoutWithBlock:nil]); +} + +- (void)testConfigureLayoutBlockWorksWithValidBlock +{ + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + [view configureLayoutWithBlock:^(YGLayout *layout){ + XCTAssertNotNil(layout); + layout.isEnabled = YES; + layout.width = 25; + }]; + + XCTAssertTrue(view.yoga.isEnabled); + XCTAssertEqual(view.yoga.width, 25); +} + - (void)testNodesAreDeallocedWithSingleView { __weak YGLayout *layoutRef = nil;