From 14f7e8bb2ceddefed6dfa2882d727872484cc507 Mon Sep 17 00:00:00 2001 From: vvveiii Date: Thu, 13 Aug 2020 13:24:14 +0800 Subject: [PATCH] [YogaKit] support auto apply layout. - support auto apply layout - build Yoga & YogaKit framework as staticlib; - update YogaKitSample. --- Yoga.podspec | 4 +- YogaKit.podspec | 3 +- YogaKit/Source/UIView+Yoga.h | 5 ++ YogaKit/Source/UIView+Yoga.m | 85 +++++++++++++++++++ YogaKit/Source/YGLayout.m | 46 ++++++++-- YogaKit/YogaKitSample/Podfile | 4 +- YogaKit/YogaKitSample/Podfile.lock | 37 ++++---- .../YogaKitSample.xcodeproj/project.pbxproj | 40 +++------ .../ExamplesViewController.swift | 29 ++++--- .../YogaKitSample/YogaKitSample/Info.plist | 2 + .../ViewControllers/BasicViewController.swift | 10 ++- .../LayoutInclusionViewController.swift | 10 +-- .../Views/SingleLabelCollectionCell.swift | 1 - 13 files changed, 200 insertions(+), 76 deletions(-) diff --git a/Yoga.podspec b/Yoga.podspec index 2b09977d..76244f65 100644 --- a/Yoga.podspec +++ b/Yoga.podspec @@ -5,7 +5,7 @@ Pod::Spec.new do |spec| spec.name = 'Yoga' - spec.version = '1.14.0' + spec.version = '1.14.1' spec.license = { :type => 'MIT', :file => "LICENSE" } spec.homepage = 'https://yogalayout.com/' spec.documentation_url = 'https://yogalayout.com/docs' @@ -34,5 +34,5 @@ Pod::Spec.new do |spec| ] spec.source_files = 'yoga/**/*.{c,h,cpp}' spec.public_header_files = 'yoga/{Yoga,YGEnums,YGMacros,YGNode,YGStyle,YGValue}.h' - + spec.static_framework = true end diff --git a/YogaKit.podspec b/YogaKit.podspec index 4fee15ec..042d1b11 100644 --- a/YogaKit.podspec +++ b/YogaKit.podspec @@ -23,7 +23,7 @@ podspec = Pod::Spec.new do |spec| spec.ios.deployment_target = '8.0' spec.ios.frameworks = 'UIKit' spec.module_name = 'YogaKit' - spec.dependency 'Yoga', '~> 1.14' + spec.dependency 'Yoga', '~> 1.14.1' # Fixes the bug related the xcode 11 not able to find swift related frameworks. # https://github.com/Carthage/Carthage/issues/2825 # https://twitter.com/krzyzanowskim/status/1151549874653081601?s=21 @@ -32,6 +32,7 @@ podspec = Pod::Spec.new do |spec| spec.public_header_files = 'YogaKit/Source/{YGLayout,UIView+Yoga}.h' spec.private_header_files = 'YogaKit/Source/YGLayout+Private.h' spec.swift_version = '5.1' + spec.static_framework = true end # See https://github.com/facebook/yoga/pull/366 diff --git a/YogaKit/Source/UIView+Yoga.h b/YogaKit/Source/UIView+Yoga.h index 4c85dcc4..fb730c38 100644 --- a/YogaKit/Source/UIView+Yoga.h +++ b/YogaKit/Source/UIView+Yoga.h @@ -34,4 +34,9 @@ typedef void (^YGLayoutConfigurationBlock)(YGLayout* layout); @end + +@interface UIView (YogaKitAutoApplyLayout) + +@end + NS_ASSUME_NONNULL_END diff --git a/YogaKit/Source/UIView+Yoga.m b/YogaKit/Source/UIView+Yoga.m index e472c9c7..117ae319 100644 --- a/YogaKit/Source/UIView+Yoga.m +++ b/YogaKit/Source/UIView+Yoga.m @@ -35,3 +35,88 @@ static const void* kYGYogaAssociatedKey = &kYGYogaAssociatedKey; } @end + + +static const void* kYGBoundsSizeAssociatedKey = &kYGBoundsSizeAssociatedKey; +static void YogaSwizzleInstanceMethod(Class cls, SEL originalSelector, SEL swizzledSelector); + +@implementation UIView (YogaKitAutoApplyLayout) + ++ (void)load { + static dispatch_once_t onceToken = 0; + dispatch_once(&onceToken, ^{ + YogaSwizzleInstanceMethod(self, @selector(initWithFrame:), @selector(_yoga_initWithFrame:)); + YogaSwizzleInstanceMethod(self, @selector(setFrame:), @selector(_yoga_setFrame:)); + YogaSwizzleInstanceMethod(self, @selector(setBounds:), @selector(_yoga_setBounds:)); + }); +} + +- (CGSize)_yoga_boundsSize { + NSValue *value = (NSValue *)objc_getAssociatedObject(self, kYGBoundsSizeAssociatedKey); + + return value ? value.CGSizeValue : CGSizeMake(YGUndefined, YGUndefined); +} + +- (void)set_yoga_boundsSize:(CGSize)size { + objc_setAssociatedObject(self, + kYGBoundsSizeAssociatedKey, + [NSValue valueWithCGSize:size], + OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (instancetype)_yoga_initWithFrame:(CGRect)frame { + id _self = [self _yoga_initWithFrame:frame]; + if (_self) { + [self _yoga_applyLayout]; + } + + return _self; +} + +- (void)_yoga_setFrame:(CGRect)frame { + [self _yoga_setFrame:frame]; + + [self _yoga_applyLayout]; +} + +- (void)_yoga_setBounds:(CGRect)bounds { + [self _yoga_setBounds:bounds]; + + [self _yoga_applyLayout]; +} + +- (void)_yoga_applyLayout { + if (self.isYogaEnabled && self.yoga.isEnabled) { + CGSize size = self.bounds.size; + CGSize prev = self._yoga_boundsSize; + if (!CGSizeEqualToSize(size, prev)) { + self._yoga_boundsSize = size; + [self.yoga applyLayoutPreservingOrigin:YES]; + } + } +} + +@end + + +static void YogaSwizzleInstanceMethod(Class cls, SEL originalSelector, SEL swizzledSelector) { + if (!cls || !originalSelector || !swizzledSelector) { + return; + } + + Method originalMethod = class_getInstanceMethod(cls, originalSelector); + Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector); + if (!originalMethod || !swizzledMethod) { + return; + } + + IMP swizzledIMP = method_getImplementation(swizzledMethod); + if (class_addMethod(cls, originalSelector, swizzledIMP, method_getTypeEncoding(swizzledMethod))) { + class_replaceMethod(cls, + swizzledSelector, + method_getImplementation(originalMethod), + method_getTypeEncoding(originalMethod)); + } else { + method_exchangeImplementations(originalMethod, swizzledMethod); + } +} diff --git a/YogaKit/Source/YGLayout.m b/YogaKit/Source/YGLayout.m index 4a95a5ca..c64a30ea 100644 --- a/YogaKit/Source/YGLayout.m +++ b/YogaKit/Source/YGLayout.m @@ -162,6 +162,7 @@ static YGConfigRef globalConfig; @property(nonatomic, weak, readonly) UIView* view; @property(nonatomic, assign, readonly) BOOL isUIView; +@property(nonatomic, assign) BOOL isApplingLayout; @end @@ -292,11 +293,19 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio) } - (void)applyLayout { + if (self.isApplingLayout) { + return; + } + [self calculateLayoutWithSize:self.view.bounds.size]; YGApplyLayoutToViewHierarchy(self.view, NO); } - (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin { + if (self.isApplingLayout) { + return; + } + [self calculateLayoutWithSize:self.view.bounds.size]; YGApplyLayoutToViewHierarchy(self.view, preserveOrigin); } @@ -304,6 +313,10 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio) - (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin dimensionFlexibility: (YGDimensionFlexibility)dimensionFlexibility { + if (self.isApplingLayout) { + return; + } + CGSize size = self.view.bounds.size; if (dimensionFlexibility & YGDimensionFlexibilityFlexibleWidth) { size.width = YGUndefined; @@ -463,12 +476,22 @@ static void YGApplyLayoutToViewHierarchy(UIView* view, BOOL preserveOrigin) { [NSThread isMainThread], @"Framesetting should only be done on the main thread."); + if (!view.isYogaEnabled || !view.yoga.isEnabled) { + return; + } + const YGLayout* yoga = view.yoga; + if (yoga.isApplingLayout) { + return; + } + if (!yoga.isIncludedInLayout) { return; } + yoga.isApplingLayout = YES; + YGNodeRef node = yoga.node; const CGPoint topLeft = { YGNodeLayoutGetLeft(node), @@ -481,7 +504,7 @@ static void YGApplyLayoutToViewHierarchy(UIView* view, BOOL preserveOrigin) { }; const CGPoint origin = preserveOrigin ? view.frame.origin : CGPointZero; - view.frame = (CGRect){ + CGRect frame = (CGRect){ .origin = { .x = YGRoundPixelValue(topLeft.x + origin.x), @@ -489,18 +512,31 @@ static void YGApplyLayoutToViewHierarchy(UIView* view, BOOL preserveOrigin) { }, .size = { - .width = YGRoundPixelValue(bottomRight.x) - - YGRoundPixelValue(topLeft.x), - .height = YGRoundPixelValue(bottomRight.y) - - YGRoundPixelValue(topLeft.y), + .width = MAX(YGRoundPixelValue(bottomRight.x) - + YGRoundPixelValue(topLeft.x), 0), + .height = MAX(YGRoundPixelValue(bottomRight.y) - + YGRoundPixelValue(topLeft.y), 0), }, }; + // use bounds/center and not frame if non-identity transform. + view.bounds = (CGRect) { + .origin = view.bounds.origin, + .size = frame.size + }; + + view.center = (CGPoint) { + .x = YGRoundPixelValue(CGRectGetMinX(frame) + CGRectGetWidth(frame) * 0.5), + .y = YGRoundPixelValue(CGRectGetMinY(frame) + CGRectGetHeight(frame) * 0.5) + }; + if (!yoga.isLeaf) { for (NSUInteger i = 0; i < view.subviews.count; i++) { YGApplyLayoutToViewHierarchy(view.subviews[i], NO); } } + + yoga.isApplingLayout = NO; } @end diff --git a/YogaKit/YogaKitSample/Podfile b/YogaKit/YogaKitSample/Podfile index ab7eca4d..e5e98666 100644 --- a/YogaKit/YogaKitSample/Podfile +++ b/YogaKit/YogaKitSample/Podfile @@ -1,6 +1,8 @@ +platform :ios, '9.0' use_frameworks! target 'YogaKitSample' do + pod 'Yoga', :path => '../../Yoga.podspec' pod 'YogaKit', :path => '../../YogaKit.podspec' - pod 'IGListKit', '~> 2.1.0' + pod 'IGListKit', '~> 4.0.0' end diff --git a/YogaKit/YogaKitSample/Podfile.lock b/YogaKit/YogaKitSample/Podfile.lock index 8600fade..a66202ea 100644 --- a/YogaKit/YogaKitSample/Podfile.lock +++ b/YogaKit/YogaKitSample/Podfile.lock @@ -1,26 +1,33 @@ PODS: - - IGListKit (2.1.0): - - IGListKit/Default (= 2.1.0) - - IGListKit/Default (2.1.0): - - IGListKit/Diffing - - IGListKit/Diffing (2.1.0) - - Yoga (1.7.0) - - YogaKit (1.7.0): - - Yoga (~> 1.7) + - IGListDiffKit (4.0.0) + - IGListKit (4.0.0): + - IGListDiffKit (= 4.0.0) + - Yoga (1.14.1) + - YogaKit (1.18.1): + - Yoga (~> 1.14.1) DEPENDENCIES: - - IGListKit (~> 2.1.0) + - IGListKit (~> 4.0.0) + - Yoga (from `../../Yoga.podspec`) - YogaKit (from `../../YogaKit.podspec`) +SPEC REPOS: + trunk: + - IGListDiffKit + - IGListKit + EXTERNAL SOURCES: + Yoga: + :path: "../../Yoga.podspec" YogaKit: - :path: ../../YogaKit.podspec + :path: "../../YogaKit.podspec" SPEC CHECKSUMS: - IGListKit: b826c68ef7a4ae1626c09d4d3e1ea7a169e6c36e - Yoga: 2ed1d7accfef3610a67f58c0cf101a0662137f2c - YogaKit: 31576530e8fcae3175469719ec3212397403330b + IGListDiffKit: 665d6cf43ce726e676013db9c7d6c4294259b6b2 + IGListKit: fd5a5d21935298f5849fa49d426843cff97b77c7 + Yoga: 1b62f19e549f5e174fc935ba76a47a8d9b60211e + YogaKit: befe87ed72becf4125f290a33af021e9992712c7 -PODFILE CHECKSUM: 216f8e7127767709e0e43f3711208d238fa5c404 +PODFILE CHECKSUM: 31f0f3ccdee77adc2f4b58b4772186c206fd1446 -COCOAPODS: 1.1.1 +COCOAPODS: 1.9.1 diff --git a/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/project.pbxproj b/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/project.pbxproj index 01b15da3..7094eefa 100644 --- a/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/project.pbxproj +++ b/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/project.pbxproj @@ -1,10 +1,3 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - // !$*UTF8*$! { archiveVersion = 1; @@ -178,7 +171,6 @@ 13687D401DF8748300E7C260 /* Frameworks */, 13687D411DF8748300E7C260 /* Resources */, FA2FB9DD6471BDD3FBCE503B /* [CP] Embed Pods Frameworks */, - 6E01EB987F1564F3D71EBE5A /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -233,6 +225,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -272,28 +265,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-YogaKitSample-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; - showEnvVarsInLog = 0; - }; - 6E01EB987F1564F3D71EBE5A /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-YogaKitSample/Pods-YogaKitSample-resources.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; FA2FB9DD6471BDD3FBCE503B /* [CP] Embed Pods Frameworks */ = { @@ -302,13 +283,18 @@ files = ( ); inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-YogaKitSample/Pods-YogaKitSample-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/IGListDiffKit/IGListDiffKit.framework", + "${BUILT_PRODUCTS_DIR}/IGListKit/IGListKit.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IGListDiffKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IGListKit.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-YogaKitSample/Pods-YogaKitSample-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-YogaKitSample/Pods-YogaKitSample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -446,7 +432,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_INSTALL_OBJC_HEADER = NO; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -461,7 +447,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.facebook.YogaKitSample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_INSTALL_OBJC_HEADER = NO; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/YogaKit/YogaKitSample/YogaKitSample/ExamplesViewController.swift b/YogaKit/YogaKitSample/YogaKitSample/ExamplesViewController.swift index c46f0dd6..f7a19d56 100644 --- a/YogaKit/YogaKitSample/YogaKitSample/ExamplesViewController.swift +++ b/YogaKit/YogaKitSample/YogaKitSample/ExamplesViewController.swift @@ -18,12 +18,12 @@ private final class ExampleModel { } } -extension ExampleModel: IGListDiffable { +extension ExampleModel: ListDiffable { fileprivate func diffIdentifier() -> NSObjectProtocol { return title as NSString } - fileprivate func isEqual(toDiffableObject object: IGListDiffable?) -> Bool { + fileprivate func isEqual(toDiffableObject object: ListDiffable?) -> Bool { guard let otherObj = object as? ExampleModel else { return false } return (title == otherObj.title) && @@ -31,11 +31,11 @@ extension ExampleModel: IGListDiffable { } } -final class ExamplesViewController: UIViewController, IGListAdapterDataSource, IGListSingleSectionControllerDelegate { - private lazy var adapter: IGListAdapter = { - return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0) +final class ExamplesViewController: UIViewController, ListAdapterDataSource, ListSingleSectionControllerDelegate { + private lazy var adapter: ListAdapter = { + return ListAdapter(updater: ListAdapterUpdater(), viewController: self, workingRangeSize: 0) }() - private let collectionView = IGListCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + private let collectionView = ListCollectionView(frame: .zero) // Update this to array to create more examples. @@ -47,6 +47,7 @@ final class ExamplesViewController: UIViewController, IGListAdapterDataSource, I override func viewDidLoad() { super.viewDidLoad() title = "Examples" + collectionView.backgroundColor = .clear view.addSubview(collectionView) adapter.collectionView = collectionView adapter.dataSource = self @@ -59,16 +60,16 @@ final class ExamplesViewController: UIViewController, IGListAdapterDataSource, I //MARK: IGListAdapterDataSource - func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] { - return models as [IGListDiffable] + func objects(for listAdapter: ListAdapter) -> [ListDiffable] { + return models as [ListDiffable] } - func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController { - let sizeBlock: IGListSingleSectionCellSizeBlock = { (model, context) in + func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController { + let sizeBlock: ListSingleSectionCellSizeBlock = { (model, context) in return CGSize(width: (context?.containerSize.width)!, height: 75.0) } - let configureBlock: IGListSingleSectionCellConfigureBlock = { (model, cell) in + let configureBlock: ListSingleSectionCellConfigureBlock = { (model, cell) in guard let m = model as? ExampleModel, let c = cell as? SingleLabelCollectionCell else { return } @@ -76,18 +77,18 @@ final class ExamplesViewController: UIViewController, IGListAdapterDataSource, I c.label.text = m.title } - let sectionController = IGListSingleSectionController(cellClass: SingleLabelCollectionCell.self, + let sectionController = ListSingleSectionController(cellClass: SingleLabelCollectionCell.self, configureBlock: configureBlock, sizeBlock: sizeBlock) sectionController.selectionDelegate = self return sectionController } - func emptyView(for listAdapter: IGListAdapter) -> UIView? { return nil } + func emptyView(for listAdapter: ListAdapter) -> UIView? { return nil } //MARK: IGListSingleSectionControllerDelegate - func didSelect(_ sectionController: IGListSingleSectionController) { + func didSelect(_ sectionController: ListSingleSectionController, with object: Any) { let section = adapter.section(for: sectionController) let model = models[section] diff --git a/YogaKit/YogaKitSample/YogaKitSample/Info.plist b/YogaKit/YogaKitSample/YogaKitSample/Info.plist index 22ca2cd4..c15be7ff 100644 --- a/YogaKit/YogaKitSample/YogaKitSample/Info.plist +++ b/YogaKit/YogaKitSample/YogaKitSample/Info.plist @@ -32,5 +32,7 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIUserInterfaceStyle + Light diff --git a/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/BasicViewController.swift b/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/BasicViewController.swift index 07059f1f..9637baef 100644 --- a/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/BasicViewController.swift +++ b/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/BasicViewController.swift @@ -32,22 +32,24 @@ final class BasicViewController: UIViewController { } root.addSubview(child1) - let child2 = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200)) + let child2 = UIView() child2.backgroundColor = .green child2.configureLayout { (layout) in layout.isEnabled = true layout.alignSelf = .flexEnd + layout.width = 200 + layout.height = 200 } root.addSubview(child2) - let child3 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) + let child3 = UIView() child3.backgroundColor = .yellow child3.configureLayout { (layout) in layout.isEnabled = true layout.alignSelf = .flexStart + layout.width = 100 + layout.height = 100 } root.addSubview(child3) - - root.yoga.applyLayout(preservingOrigin: true) } } diff --git a/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/LayoutInclusionViewController.swift b/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/LayoutInclusionViewController.swift index 897b8590..ced3693f 100644 --- a/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/LayoutInclusionViewController.swift +++ b/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/LayoutInclusionViewController.swift @@ -51,9 +51,9 @@ final class LayoutInclusionViewController: UIViewController { } contentView.addSubview(disappearingView) - button.setTitle("Add Blue View", for: UIControlState.selected) - button.setTitle("Remove Blue View", for: UIControlState.normal) - button.addTarget(self, action: #selector(buttonWasTapped), for: UIControlEvents.touchUpInside) + button.setTitle("Add Blue View", for: .selected) + button.setTitle("Remove Blue View", for: .normal) + button.addTarget(self, action: #selector(buttonWasTapped), for: UIControl.Event.touchUpInside) button.configureLayout { (layout) in layout.isEnabled = true layout.height = 300 @@ -61,12 +61,10 @@ final class LayoutInclusionViewController: UIViewController { layout.alignSelf = .center } root.addSubview(button) - - root.yoga.applyLayout(preservingOrigin: false) } // MARK - UIButton Action - func buttonWasTapped() { + @objc func buttonWasTapped() { button.isSelected = !button.isSelected button.isUserInteractionEnabled = false diff --git a/YogaKit/YogaKitSample/YogaKitSample/Views/SingleLabelCollectionCell.swift b/YogaKit/YogaKitSample/YogaKitSample/Views/SingleLabelCollectionCell.swift index 50fa9042..19ec7006 100644 --- a/YogaKit/YogaKitSample/YogaKitSample/Views/SingleLabelCollectionCell.swift +++ b/YogaKit/YogaKitSample/YogaKitSample/Views/SingleLabelCollectionCell.swift @@ -42,7 +42,6 @@ final class SingleLabelCollectionCell: UICollectionViewCell { override func layoutSubviews() { super.layoutSubviews() - contentView.yoga.applyLayout(preservingOrigin: false) label.frame = contentView.bounds } }