From 4fc1657f2c40655373d93cf439b784fa2eae1779 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 6 Jun 2023 14:56:44 -0700 Subject: [PATCH] Basic CocoaPods Validation (#1303) Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1303 This gets `pod lib lint` and building the sample app with xcbuild passing (using https://github.com/facebook/yoga/pull/1105 as a template). Reviewed By: cipolleschi Differential Revision: D46470738 fbshipit-source-id: f66f6c6efc1b7cf1443fbca0815a24801c16a626 --- .github/workflows/validate-apple.yml | 14 ++--- Yoga.podspec | 10 ++-- YogaKit.podspec | 13 ++--- YogaKit/.swift-version | 1 - YogaKit/YogaKitSample/Podfile | 13 ++++- YogaKit/YogaKitSample/Podfile.lock | 37 ++++++++----- .../YogaKitSample.xcodeproj/project.pbxproj | 55 ++++++++----------- .../ExamplesViewController.swift | 35 ++++++------ .../ViewControllers/BasicViewController.swift | 19 ++++--- .../LayoutInclusionViewController.swift | 9 +-- 10 files changed, 109 insertions(+), 97 deletions(-) delete mode 100644 YogaKit/.swift-version diff --git a/.github/workflows/validate-apple.yml b/.github/workflows/validate-apple.yml index 3b569812d5..92c891d7cd 100644 --- a/.github/workflows/validate-apple.yml +++ b/.github/workflows/validate-apple.yml @@ -9,7 +9,7 @@ on: jobs: lint-pods: - name: Lint + name: Lint pod runs-on: macos-latest steps: @@ -18,12 +18,11 @@ jobs: - name: Setup uses: ./.github/actions/setup-apple - - name: pod spec lint - run: pod spec lint --verbose - continue-on-error: true # Apple Build is Broken + - name: pod lib lint + run: pod lib lint --verbose --include-podspecs=**/*.podspec build-sample: - name: Build [${{ matrix.mode }}] + name: Build sample [${{ matrix.mode }}] runs-on: macos-latest strategy: matrix: @@ -38,9 +37,10 @@ jobs: - name: pod install run: pod install working-directory: ./YogaKit/YogaKitSample - continue-on-error: true # Apple Build is Broken - # TODO: xcodebuild + - name: xcodebuild YogaKitSample.xcworkspace + run: xcodebuild -workspace YogaKitSample.xcworkspace -scheme YogaKitSample + working-directory: ./YogaKit/YogaKitSample clang-format: name: Format diff --git a/Yoga.podspec b/Yoga.podspec index 4ba88080f2..1c01089c86 100644 --- a/Yoga.podspec +++ b/Yoga.podspec @@ -6,7 +6,7 @@ Pod::Spec.new do |spec| spec.name = 'Yoga' - spec.version = '1.14.0' + spec.version = '2.0.0-beta.1' spec.license = { :type => 'MIT', :file => "LICENSE" } spec.homepage = 'https://yogalayout.com/' spec.documentation_url = 'https://yogalayout.com/docs' @@ -17,9 +17,11 @@ Pod::Spec.new do |spec| spec.authors = 'Facebook' spec.source = { :git => 'https://github.com/facebook/yoga.git', - :tag => spec.version.to_s, + :tag => "v#{spec.version.to_s}", } - spec.platforms = { :ios => "8.0", :osx => "10.7", :tvos => "10.0", :watchos => "2.0" } + + spec.ios.deployment_target = "13.4" + spec.module_name = 'yoga' spec.requires_arc = false spec.pod_target_xcconfig = { @@ -36,5 +38,5 @@ Pod::Spec.new do |spec| ] spec.source_files = 'yoga/**/*.{h,cpp}' spec.public_header_files = 'yoga/{Yoga,YGEnums,YGMacros,YGValue}.h' - + spec.swift_version = '5.1' end diff --git a/YogaKit.podspec b/YogaKit.podspec index ac6a5b0971..07b2448046 100644 --- a/YogaKit.podspec +++ b/YogaKit.podspec @@ -5,7 +5,7 @@ podspec = Pod::Spec.new do |spec| spec.name = 'YogaKit' - spec.version = '1.18.1' + spec.version = '2.0.0-beta.1' spec.license = { :type => 'MIT', :file => "LICENSE" } spec.homepage = 'https://facebook.github.io/yoga/' spec.documentation_url = 'https://facebook.github.io/yoga/docs/' @@ -16,18 +16,13 @@ podspec = Pod::Spec.new do |spec| spec.authors = 'Facebook' spec.source = { :git => 'https://github.com/facebook/yoga.git', - :tag => "1.18.0", + :tag => "v#{spec.version.to_s}", } - spec.platform = :ios - spec.ios.deployment_target = '8.0' + spec.platforms = { :ios => "13.4" } spec.ios.frameworks = 'UIKit' spec.module_name = 'YogaKit' - spec.dependency 'Yoga', '~> 1.14' - # 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 - spec.pod_target_xcconfig = {"LD_VERIFY_BITCODE": "NO"} + spec.dependency 'Yoga', "~> #{spec.version.to_s}" spec.source_files = 'YogaKit/Source/*.{h,m,swift}' spec.public_header_files = 'YogaKit/Source/{YGLayout,UIView+Yoga}.h' spec.private_header_files = 'YogaKit/Source/YGLayout+Private.h' diff --git a/YogaKit/.swift-version b/YogaKit/.swift-version deleted file mode 100644 index b502146930..0000000000 --- a/YogaKit/.swift-version +++ /dev/null @@ -1 +0,0 @@ -3.0.2 diff --git a/YogaKit/YogaKitSample/Podfile b/YogaKit/YogaKitSample/Podfile index ab7eca4df1..eb81489744 100644 --- a/YogaKit/YogaKitSample/Podfile +++ b/YogaKit/YogaKitSample/Podfile @@ -1,6 +1,17 @@ use_frameworks! +platform :ios, "13.4" + target 'YogaKitSample' do pod 'YogaKit', :path => '../../YogaKit.podspec' - pod 'IGListKit', '~> 2.1.0' + pod 'Yoga', :path => '../../Yoga.podspec' + pod 'IGListKit', '~> 4.0.0' +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.4' + end + end end diff --git a/YogaKit/YogaKitSample/Podfile.lock b/YogaKit/YogaKitSample/Podfile.lock index 8600fade7b..a3207cc7c0 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 (2.0.0-beta.1) + - YogaKit (2.0.0-beta.1): + - Yoga (~> 2.0.0-beta.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: 090c6851e548d085d6211b5466b57ba8f4013a90 + YogaKit: 5ae1939cd7516fdf6c343abb4b4aa381c9911ccf -PODFILE CHECKSUM: 216f8e7127767709e0e43f3711208d238fa5c404 +PODFILE CHECKSUM: e5d9841ef739884db00a29f2d529d16bf247a4ca -COCOAPODS: 1.1.1 +COCOAPODS: 1.12.1 diff --git a/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/project.pbxproj b/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/project.pbxproj index 01b15da3c5..22c9849d44 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 = ( ); @@ -272,28 +264,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 +282,22 @@ 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", + "${BUILT_PRODUCTS_DIR}/Yoga/yoga.framework", + "${BUILT_PRODUCTS_DIR}/YogaKit/YogaKit.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IGListDiffKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IGListKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/yoga.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YogaKit.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 */ @@ -366,7 +355,7 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGNING_ALLOWED = NO; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -385,7 +374,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.1; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -414,7 +403,7 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGNING_ALLOWED = NO; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; @@ -427,7 +416,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.1; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -446,7 +435,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_INSTALL_OBJC_HEADER = NO; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.1; }; name = Debug; }; @@ -461,7 +450,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.facebook.YogaKitSample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_INSTALL_OBJC_HEADER = NO; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.1; }; name = Release; }; @@ -471,7 +460,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = YogaKitSampleTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.2; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.YogaKitSampleTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -485,7 +474,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = YogaKitSampleTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.2; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.YogaKitSampleTests; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/YogaKit/YogaKitSample/YogaKitSample/ExamplesViewController.swift b/YogaKit/YogaKitSample/YogaKitSample/ExamplesViewController.swift index d7a6a6a5fd..d5aa793fda 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,12 +31,16 @@ extension ExampleModel: IGListDiffable { } } -final class ExamplesViewController: UIViewController, IGListAdapterDataSource, IGListSingleSectionControllerDelegate { - private lazy var adapter: IGListAdapter = { - return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0) - }() - private let collectionView = IGListCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) +final class ExamplesViewController: UIViewController, ListAdapterDataSource, ListSingleSectionControllerDelegate { + private lazy var adapter: ListAdapter = { + return ListAdapter(updater: ListAdapterUpdater(), viewController: self, workingRangeSize: 0) + }() + private lazy var collectionView: UICollectionView = { + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + collectionView.backgroundColor = UIColor.systemBackground + return collectionView + }() // Update this to array to create more examples. private let models: [ExampleModel] = [ExampleModel(title: "Basic Layout", controllerClass: BasicViewController.self), @@ -59,16 +63,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 +80,17 @@ 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/ViewControllers/BasicViewController.swift b/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/BasicViewController.swift index d8f6396edc..424433e621 100644 --- a/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/BasicViewController.swift +++ b/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/BasicViewController.swift @@ -10,11 +10,11 @@ import YogaKit final class BasicViewController: UIViewController { override func viewDidLoad() { + super.viewDidLoad() let containerSize = self.view.bounds.size - let root = self.view! - root.backgroundColor = .white - root.configureLayout { (layout) in + view.backgroundColor = UIColor.systemBackground + view.configureLayout { (layout) in layout.isEnabled = true layout.width = YGValue(containerSize.width) layout.height = YGValue(containerSize.height) @@ -30,24 +30,29 @@ final class BasicViewController: UIViewController { layout.height = 10 layout.marginBottom = 25 } - root.addSubview(child1) + view.addSubview(child1) let child2 = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200)) child2.backgroundColor = .green child2.configureLayout { (layout) in layout.isEnabled = true layout.alignSelf = .flexEnd + layout.width = 200 + layout.height = 200 } - root.addSubview(child2) + view.addSubview(child2) let child3 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) child3.backgroundColor = .yellow child3.configureLayout { (layout) in layout.isEnabled = true layout.alignSelf = .flexStart + layout.width = 100 + layout.height = 100 + } - root.addSubview(child3) + view.addSubview(child3) - root.yoga.applyLayout(preservingOrigin: true) + view.yoga.applyLayout(preservingOrigin: true) } } diff --git a/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/LayoutInclusionViewController.swift b/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/LayoutInclusionViewController.swift index 156a16b08f..2b51d915f7 100644 --- a/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/LayoutInclusionViewController.swift +++ b/YogaKit/YogaKitSample/YogaKitSample/ViewControllers/LayoutInclusionViewController.swift @@ -14,6 +14,7 @@ final class LayoutInclusionViewController: UIViewController { private let contentView: UIView = UIView(frame: .zero) override func viewDidLoad() { + super.viewDidLoad() let root = self.view! root.backgroundColor = .white root.configureLayout { (layout) in @@ -51,9 +52,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: .touchUpInside) button.configureLayout { (layout) in layout.isEnabled = true layout.height = 300 @@ -66,7 +67,7 @@ final class LayoutInclusionViewController: UIViewController { } // MARK - UIButton Action - func buttonWasTapped() { + @objc func buttonWasTapped() { button.isSelected = !button.isSelected button.isUserInteractionEnabled = false