diff --git a/.gitignore b/.gitignore index bfacd4a..57eb564 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ DerivedData *.gcda *.gcno .DS_Store +.coveralls.yml diff --git a/.travis.yml b/.travis.yml index 0743aeb..36f9872 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,17 @@ sudo: false +osx_image: xcode10 language: objective-c +rvm: + - 2.6.0 xcode_project: PureLayout/PureLayout.xcodeproj -matrix: - include: - - xcode_sdk: iphonesimulator - xcode_scheme: PureLayout_iOS - - xcode_sdk: macosx - xcode_scheme: PureLayout_Mac - before_install: - - gem install slather --no-ri --no-rdoc + - rvm install 2.6.0 + - gem install slather --no-document + +script: + - xcodebuild test -project PureLayout/PureLayout.xcodeproj -scheme PureLayout_iOS -destination 'platform=iOS Simulator,name=iPhone X,OS=11.2' + - xcodebuild test -project PureLayout/PureLayout.xcodeproj -scheme PureLayout_iOS -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.2' + - xcodebuild test -project PureLayout/PureLayout.xcodeproj -scheme PureLayout_iOS -destination 'platform=iOS Simulator,name=iPhone 5s,OS=9.0' + - xcodebuild test -project PureLayout/PureLayout.xcodeproj -scheme PureLayout_Mac -destination 'platform=OS X,arch=x86_64' after_success: slather diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..bea3338 --- /dev/null +++ b/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' +gem 'slather' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..427c77f --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,45 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (2.3.6) + activesupport (5.1.5) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) + minitest (~> 5.1) + tzinfo (~> 1.1) + atomos (0.1.2) + claide (1.0.2) + clamp (0.6.5) + colored2 (3.1.2) + concurrent-ruby (1.0.5) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + mini_portile2 (2.3.0) + minitest (5.11.3) + nanaimo (0.2.4) + nokogiri (1.8.2) + mini_portile2 (~> 2.3.0) + slather (2.4.5) + CFPropertyList (~> 2.2) + activesupport (>= 4.0.2) + clamp (~> 0.6) + nokogiri (~> 1.8.2) + xcodeproj (~> 1.4) + thread_safe (0.3.6) + tzinfo (1.2.5) + thread_safe (~> 0.1) + xcodeproj (1.5.7) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.2) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.2.4) + +PLATFORMS + ruby + +DEPENDENCIES + slather + +BUNDLED WITH + 1.16.1 diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..d386a44 --- /dev/null +++ b/Package.swift @@ -0,0 +1,19 @@ +// swift-tools-version:5.1 + +import PackageDescription + +let package = Package( + name: "PureLayout", + platforms: [.iOS(.v9), .macOS(.v10_10), .tvOS(.v9)], + products: [ + .library( + name: "PureLayout", + targets: ["PureLayout"]) + ], + targets: [ + .target( + name: "PureLayout", + path: "PureLayout/PureLayout", + publicHeadersPath: "include") + ] +) diff --git a/PureLayout.podspec b/PureLayout.podspec index 6f533e9..584b9cd 100644 --- a/PureLayout.podspec +++ b/PureLayout.podspec @@ -1,20 +1,19 @@ Pod::Spec.new do |s| s.name = 'PureLayout' - s.version = '3.0.1' - s.homepage = 'https://github.com/PureLayout/PureLayout' - s.license = { :type => 'MIT', :file => 'LICENSE' } + s.version = '3.1.9' + s.homepage = "https://github.com/#{s.name}/#{s.name}" + s.license = { type: 'MIT', file: 'LICENSE' } s.author = 'Tyler Fox' - s.ios.deployment_target = '6.0' - s.osx.deployment_target = '10.7' + s.ios.deployment_target = '9.0' + s.osx.deployment_target = '10.9' s.tvos.deployment_target = '9.0' - s.source = { :git => 'https://github.com/PureLayout/PureLayout.git', :tag => 'v3.0.1' } - s.source_files = 'PureLayout/PureLayout' - s.requires_arc = true + s.source = { git: "#{s.homepage}.git", tag: "v#{s.version}" } + s.source_files = "#{s.name}/#{s.name}", "#{s.name}/#{s.name}/include" s.summary = 'The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. Objective-C and Swift compatible.' s.description = <<-DESC - # PureLayout - The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. PureLayout extends `UIView`/`NSView`, `NSArray`, and `NSLayoutConstraint` with a comprehensive Auto Layout API that is modeled after Apple's own frameworks. PureLayout is an Objective-C library that also works (and looks!) great with Swift using a bridging header. + # PureLayout + The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. PureLayout extends `UIView`/`NSView`, `NSArray`, and `NSLayoutConstraint` with a comprehensive Auto Layout API that is modeled after Apple's own frameworks. PureLayout is an Objective-C library that also works (and looks!) great with Swift using a bridging header. - Writing Auto Layout code from scratch isn't easy. PureLayout provides a fully capable and developer-friendly interface for Auto Layout. It is designed for clarity and simplicity, and takes inspiration from the AutoLayout UI options available in Interface Builder while delivering far more flexibility. The API is also highly efficient, as it adds only a thin layer of third party code and is engineered for maximum performance. - DESC + Writing Auto Layout code from scratch isn't easy. PureLayout provides a fully capable and developer-friendly interface for Auto Layout. It is designed for clarity and simplicity, and takes inspiration from the AutoLayout UI options available in Interface Builder while delivering far more flexibility. The API is also highly efficient, as it adds only a thin layer of third party code and is engineered for maximum performance. + DESC end diff --git a/PureLayout/3.1.9/PureLayout.podspec b/PureLayout/3.1.9/PureLayout.podspec new file mode 100644 index 0000000..584b9cd --- /dev/null +++ b/PureLayout/3.1.9/PureLayout.podspec @@ -0,0 +1,19 @@ +Pod::Spec.new do |s| + s.name = 'PureLayout' + s.version = '3.1.9' + s.homepage = "https://github.com/#{s.name}/#{s.name}" + s.license = { type: 'MIT', file: 'LICENSE' } + s.author = 'Tyler Fox' + s.ios.deployment_target = '9.0' + s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '9.0' + s.source = { git: "#{s.homepage}.git", tag: "v#{s.version}" } + s.source_files = "#{s.name}/#{s.name}", "#{s.name}/#{s.name}/include" + s.summary = 'The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. Objective-C and Swift compatible.' + s.description = <<-DESC + # PureLayout + The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. PureLayout extends `UIView`/`NSView`, `NSArray`, and `NSLayoutConstraint` with a comprehensive Auto Layout API that is modeled after Apple's own frameworks. PureLayout is an Objective-C library that also works (and looks!) great with Swift using a bridging header. + + Writing Auto Layout code from scratch isn't easy. PureLayout provides a fully capable and developer-friendly interface for Auto Layout. It is designed for clarity and simplicity, and takes inspiration from the AutoLayout UI options available in Interface Builder while delivering far more flexibility. The API is also highly efficient, as it adds only a thin layer of third party code and is engineered for maximum performance. + DESC +end diff --git a/PureLayout/Example-iOS/Demos/ALiOSDemo11ViewController.m b/PureLayout/Example-iOS/Demos/ALiOSDemo11ViewController.m index 7bfe904..a248408 100644 --- a/PureLayout/Example-iOS/Demos/ALiOSDemo11ViewController.m +++ b/PureLayout/Example-iOS/Demos/ALiOSDemo11ViewController.m @@ -37,8 +37,11 @@ - (void)updateViewConstraints { if (!self.didSetupConstraints) { - [self.scrollView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero]; - + if (@available(iOS 9.0, *)) { + [self.scrollView autoPinEdgesToSuperviewSafeAreaWithInsets:UIEdgeInsetsZero]; + } else { + [self.scrollView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero]; + } [self.contentView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero]; [self.contentView autoMatchDimension:ALDimensionWidth toDimension:ALDimensionWidth ofView:self.view]; diff --git a/PureLayout/Example-iOS/Demos/ALiOSDemo9ViewController.m b/PureLayout/Example-iOS/Demos/ALiOSDemo9ViewController.m index aaa0504..5601fea 100644 --- a/PureLayout/Example-iOS/Demos/ALiOSDemo9ViewController.m +++ b/PureLayout/Example-iOS/Demos/ALiOSDemo9ViewController.m @@ -55,7 +55,7 @@ - (void)updateViewConstraints [self.yellowView autoPinEdgeToSuperviewMargin:ALEdgeLeft]; [self.yellowView autoPinEdgeToSuperviewMargin:ALEdgeRight]; - // By aligning the yellowView to its superview's horiztonal margin axis, the yellowView will be positioned with its horizontal axis + // By aligning the yellowView to its superview's horizontal margin axis, the yellowView will be positioned with its horizontal axis // in the middle of the redView's top and bottom margins (causing it to be slightly closer to the top of the redView, since the // redView has a much larger bottom margin than top margin). [self.yellowView autoAlignAxisToSuperviewMarginAxis:ALAxisHorizontal]; diff --git a/PureLayout/Example-iOS/Demos/iOSDemo10ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo10ViewController.swift index af2f311..9a3f6bb 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo10ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo10ViewController.swift @@ -13,30 +13,30 @@ import PureLayout class iOSDemo10ViewController: UIViewController { let blueView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .blueColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .blue return view }() let redView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .redColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .red return view }() let yellowView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .yellowColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .yellow return view }() let greenView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .greenColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .green return view }() let toggleConstraintsButton: UIButton = { - let button = UIButton.newAutoLayoutView() - button.setTitle("Toggle Constraints", forState: .Normal) - button.setTitleColor(.whiteColor(), forState: .Normal) - button.setTitleColor(.grayColor(), forState: .Highlighted) + let button = UIButton.newAutoLayout() + button.setTitle("Toggle Constraints", for: UIControlState()) + button.setTitleColor(.white, for: UIControlState()) + button.setTitleColor(.gray, for: .highlighted) return button }() @@ -59,7 +59,7 @@ class iOSDemo10ViewController: UIViewController { view.addSubview(greenView) view.addSubview(toggleConstraintsButton) - toggleConstraintsButton.addTarget(self, action: "toggleConstraints:", forControlEvents: .TouchUpInside) + toggleConstraintsButton.addTarget(self, action: #selector(iOSDemo10ViewController.toggleConstraints(_:)), for: .touchUpInside) view.setNeedsUpdateConstraints() // bootstrap Auto Layout } @@ -71,22 +71,22 @@ class iOSDemo10ViewController: UIViewController { // Create and install the constraints that define the horizontal layout, because this is the one we're starting in. // Note that we use autoCreateAndInstallConstraints() here in order to easily collect all the constraints into a single array. horizontalLayoutConstraints = NSLayoutConstraint.autoCreateAndInstallConstraints { - views.autoSetViewsDimension(.Height, toSize: 40.0) - views.autoDistributeViewsAlongAxis(.Horizontal, alignedTo: .Horizontal, withFixedSpacing: 10.0, insetSpacing: true, matchedSizes: true) - self.redView.autoAlignAxisToSuperviewAxis(.Horizontal) - } + views.autoSetViewsDimension(.height, toSize: 40.0) + views.autoDistributeViews(along: .horizontal, alignedTo: .horizontal, withFixedSpacing: 10.0, insetSpacing: true, matchedSizes: true) + self.redView.autoAlignAxis(toSuperviewAxis: .horizontal) + } as NSArray? // Create the constraints that define the vertical layout, but don't install any of them - just store them for now. // Note that we use autoCreateConstraintsWithoutInstalling() here in order to both prevent the constraints from being installed automatically, // and to easily collect all the constraints into a single array. verticalLayoutConstraints = NSLayoutConstraint.autoCreateConstraintsWithoutInstalling { - views.autoSetViewsDimension(.Width, toSize: 60.0) - views.autoDistributeViewsAlongAxis(.Vertical, alignedTo: .Vertical, withFixedSpacing: 70.0, insetSpacing: true, matchedSizes: true) - self.redView.autoAlignAxisToSuperviewAxis(.Vertical) - } + views.autoSetViewsDimension(.width, toSize: 60.0) + views.autoDistributeViews(along: .vertical, alignedTo: .vertical, withFixedSpacing: 70.0, insetSpacing: true, matchedSizes: true) + self.redView.autoAlignAxis(toSuperviewAxis: .vertical) + } as NSArray? - toggleConstraintsButton.autoPinEdgeToSuperviewEdge(.Bottom, withInset: 10.0) - toggleConstraintsButton.autoAlignAxisToSuperviewAxis(.Vertical) + toggleConstraintsButton.autoPinEdge(toSuperviewEdge: .bottom, withInset: 10.0) + toggleConstraintsButton.autoAlignAxis(toSuperviewAxis: .vertical) didSetupConstraints = true } @@ -97,7 +97,7 @@ class iOSDemo10ViewController: UIViewController { /** Callback when the "Toggle Constraints" button is tapped. */ - func toggleConstraints(sender: UIButton) { + func toggleConstraints(_ sender: UIButton) { isHorizontalLayoutActive = !isHorizontalLayoutActive if (isHorizontalLayoutActive) { diff --git a/PureLayout/Example-iOS/Demos/iOSDemo11ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo11ViewController.swift index cd73e93..aa9ad05 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo11ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo11ViewController.swift @@ -12,15 +12,15 @@ import PureLayout @objc(iOSDemo11ViewController) class iOSDemo11ViewController: UIViewController { - let scrollView = UIScrollView.newAutoLayoutView() - let contentView = UIView.newAutoLayoutView() + let scrollView = UIScrollView.newAutoLayout() + let contentView = UIView.newAutoLayout() let blueLabel: UILabel = { - let label = UILabel.newAutoLayoutView() - label.backgroundColor = .blueColor() + let label = UILabel.newAutoLayout() + label.backgroundColor = .blue label.numberOfLines = 0 - label.lineBreakMode = .ByClipping - label.textColor = .whiteColor() + label.lineBreakMode = .byClipping + label.textColor = .white label.text = NSLocalizedString("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum", comment: "") return label }() @@ -42,15 +42,15 @@ class iOSDemo11ViewController: UIViewController { if (!didSetupConstraints) { - scrollView.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsetsZero) + scrollView.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets.zero) - contentView.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsetsZero) - contentView.autoMatchDimension(.Width, toDimension: .Width, ofView: view) + contentView.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets.zero) + contentView.autoMatch(.width, to: .width, of: view) - blueLabel.autoPinEdgeToSuperviewEdge(.Top, withInset: 20) - blueLabel.autoPinEdgeToSuperviewEdge(.Leading, withInset: 20) - blueLabel.autoPinEdgeToSuperviewEdge(.Trailing, withInset: 20) - blueLabel.autoPinEdgeToSuperviewEdge(.Bottom, withInset: 20) + blueLabel.autoPinEdge(toSuperviewEdge: .top, withInset: 20) + blueLabel.autoPinEdge(toSuperviewEdge: .leading, withInset: 20) + blueLabel.autoPinEdge(toSuperviewEdge: .trailing, withInset: 20) + blueLabel.autoPinEdge(toSuperviewEdge: .bottom, withInset: 20) didSetupConstraints = true } diff --git a/PureLayout/Example-iOS/Demos/iOSDemo1ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo1ViewController.swift index 61c4a88..db956db 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo1ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo1ViewController.swift @@ -13,23 +13,23 @@ import PureLayout class iOSDemo1ViewController: UIViewController { let blueView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .blueColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .blue return view }() let redView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .redColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .red return view }() let yellowView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .yellowColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .yellow return view }() let greenView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .greenColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .green return view }() @@ -54,27 +54,27 @@ class iOSDemo1ViewController: UIViewController { if (!didSetupConstraints) { // Blue view is centered on screen, with size {50 pt, 50 pt} blueView.autoCenterInSuperview() - blueView.autoSetDimensionsToSize(CGSize(width: 50.0, height: 50.0)) + blueView.autoSetDimensions(to: CGSize(width: 50.0, height: 50.0)) // Red view is positioned at the bottom right corner of the blue view, with the same width, and a height of 40 pt - redView.autoPinEdge(.Top, toEdge: .Bottom, ofView: blueView) - redView.autoPinEdge(.Left, toEdge: .Right, ofView: blueView) - redView.autoMatchDimension(.Width, toDimension: .Width, ofView: blueView) - redView.autoSetDimension(.Height, toSize: 40.0) + redView.autoPinEdge(.top, to: .bottom, of: blueView) + redView.autoPinEdge(.left, to: .right, of: blueView) + redView.autoMatch(.width, to: .width, of: blueView) + redView.autoSetDimension(.height, toSize: 40.0) // Yellow view is positioned 10 pt below the red view, extending across the screen with 20 pt insets from the edges, // and with a fixed height of 25 pt - yellowView.autoPinEdge(.Top, toEdge: .Bottom, ofView: redView, withOffset: 10.0) - yellowView.autoSetDimension(.Height, toSize: 25.0) - yellowView.autoPinEdgeToSuperviewEdge(.Left, withInset: 20.0) - yellowView.autoPinEdgeToSuperviewEdge(.Right, withInset: 20.0) + yellowView.autoPinEdge(.top, to: .bottom, of: redView, withOffset: 10.0) + yellowView.autoSetDimension(.height, toSize: 25.0) + yellowView.autoPinEdge(toSuperviewEdge: .left, withInset: 20.0) + yellowView.autoPinEdge(toSuperviewEdge: .right, withInset: 20.0) // Green view is positioned 10 pt below the yellow view, aligned to the vertical axis of its superview, // with its height twice the height of the yellow view and its width fixed to 150 pt - greenView.autoPinEdge(.Top, toEdge: .Bottom, ofView: yellowView, withOffset: 10.0) - greenView.autoAlignAxisToSuperviewAxis(.Vertical) - greenView.autoMatchDimension(.Height, toDimension: .Height, ofView: yellowView, withMultiplier: 2.0) - greenView.autoSetDimension(.Width, toSize: 150.0) + greenView.autoPinEdge(.top, to: .bottom, of: yellowView, withOffset: 10.0) + greenView.autoAlignAxis(toSuperviewAxis: .vertical) + greenView.autoMatch(.height, to: .height, of: yellowView, withMultiplier: 2.0) + greenView.autoSetDimension(.width, toSize: 150.0) didSetupConstraints = true } diff --git a/PureLayout/Example-iOS/Demos/iOSDemo2ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo2ViewController.swift index c749f95..a906a23 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo2ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo2ViewController.swift @@ -13,23 +13,23 @@ import PureLayout class iOSDemo2ViewController: UIViewController { let blueView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .blueColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .blue return view }() let redView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .redColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .red return view }() let yellowView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .yellowColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .yellow return view }() let greenView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .greenColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .green return view }() @@ -50,29 +50,29 @@ class iOSDemo2ViewController: UIViewController { override func updateViewConstraints() { if (!didSetupConstraints) { // Apply a fixed height of 50 pt to two views at once, and a fixed height of 70 pt to another two views - [redView, yellowView].autoSetViewsDimension(.Height, toSize: 50.0) - [blueView, greenView].autoSetViewsDimension(.Height, toSize: 70.0) + ([redView, yellowView] as NSArray).autoSetViewsDimension(.height, toSize: 50.0) + ([blueView, greenView] as NSArray).autoSetViewsDimension(.height, toSize: 70.0) let views = [redView, blueView, yellowView, greenView] // Match the widths of all the views - (views as NSArray).autoMatchViewsDimension(.Width) + (views as NSArray).autoMatchViewsDimension(.width) // Pin the red view 20 pt from the top layout guide of the view controller - redView.autoPinToTopLayoutGuideOfViewController(self, withInset: 20.0) + redView.autoPin(toTopLayoutGuideOf: self, withInset: 20.0) // Loop over the views, attaching the left edge to the previous view's right edge, // and the top edge to the previous view's bottom edge - views.first?.autoPinEdgeToSuperviewEdge(.Left) + views.first?.autoPinEdge(toSuperviewEdge: .left) var previousView: UIView? for view in views { if let previousView = previousView { - view.autoPinEdge(.Left, toEdge: .Right, ofView: previousView) - view.autoPinEdge(.Top, toEdge: .Bottom, ofView: previousView) + view.autoPinEdge(.left, to: .right, of: previousView) + view.autoPinEdge(.top, to: .bottom, of: previousView) } previousView = view } - views.last?.autoPinEdgeToSuperviewEdge(.Right) + views.last?.autoPinEdge(toSuperviewEdge: .right) didSetupConstraints = true } diff --git a/PureLayout/Example-iOS/Demos/iOSDemo3ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo3ViewController.swift index a29e41b..ebf5895 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo3ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo3ViewController.swift @@ -13,23 +13,23 @@ import PureLayout class iOSDemo3ViewController: UIViewController { let blueView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .blueColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .blue return view }() let redView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .redColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .red return view }() let yellowView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .yellowColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .yellow return view }() let greenView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .greenColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .green return view }() @@ -52,15 +52,15 @@ class iOSDemo3ViewController: UIViewController { let views: NSArray = [redView, blueView, yellowView, greenView] // Fix all the heights of the views to 40 pt - views.autoSetViewsDimension(.Height, toSize: 40.0) + views.autoSetViewsDimension(.height, toSize: 40.0) // Distribute the views horizontally across the screen, aligned to one another's horizontal axis, // with 10 pt spacing between them and to their superview, and their widths matched equally - views.autoDistributeViewsAlongAxis(.Horizontal, alignedTo: .Horizontal, withFixedSpacing: 10.0, insetSpacing: true, matchedSizes: true) + views.autoDistributeViews(along: .horizontal, alignedTo: .horizontal, withFixedSpacing: 10.0, insetSpacing: true, matchedSizes: true) // Align the red view to the horizontal axis of its superview. // This will end up affecting all the views, since they are all aligned to one another's horizontal axis. - self.redView.autoAlignAxisToSuperviewAxis(.Horizontal) + self.redView.autoAlignAxis(toSuperviewAxis: .horizontal) didSetupConstraints = true } diff --git a/PureLayout/Example-iOS/Demos/iOSDemo4ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo4ViewController.swift index ab1c1aa..ef99e95 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo4ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo4ViewController.swift @@ -13,25 +13,25 @@ import PureLayout class iOSDemo4ViewController: UIViewController { let blueLabel: UILabel = { - let label = UILabel.newAutoLayoutView() - label.backgroundColor = .blueColor() + let label = UILabel.newAutoLayout() + label.backgroundColor = .blue label.numberOfLines = 1 - label.lineBreakMode = .ByClipping - label.textColor = .whiteColor() + label.lineBreakMode = .byClipping + label.textColor = .white label.text = NSLocalizedString("Lorem ipsum", comment: "") return label }() let redLabel: UILabel = { - let label = UILabel.newAutoLayoutView() - label.backgroundColor = .redColor() + let label = UILabel.newAutoLayout() + label.backgroundColor = .red label.numberOfLines = 0 - label.textColor = .whiteColor() + label.textColor = .white label.text = NSLocalizedString("Lorem ipsum", comment: "") return label }() let greenView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .greenColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .green return view }() @@ -63,28 +63,28 @@ class iOSDemo4ViewController: UIViewController { if (!didSetupConstraints) { // Prevent the blueLabel from compressing smaller than required to fit its single line of text - blueLabel.setContentCompressionResistancePriority(UILayoutPriorityRequired, forAxis: .Vertical) + blueLabel.setContentCompressionResistancePriority(UILayoutPriorityRequired, for: .vertical) // Position the single-line blueLabel at the top of the screen spanning the width, with some small insets - blueLabel.autoPinToTopLayoutGuideOfViewController(self, withInset: smallPadding) - blueLabel.autoPinEdgeToSuperviewEdge(.Leading, withInset: smallPadding) - blueLabel.autoPinEdgeToSuperviewEdge(.Trailing, withInset: smallPadding) + blueLabel.autoPin(toTopLayoutGuideOf: self, withInset: smallPadding) + blueLabel.autoPinEdge(toSuperviewEdge: .leading, withInset: smallPadding) + blueLabel.autoPinEdge(toSuperviewEdge: .trailing, withInset: smallPadding) // Make the redLabel 60% of the width of the blueLabel - redLabel.autoMatchDimension(.Width, toDimension: .Width, ofView: blueLabel, withMultiplier: 0.6) + redLabel.autoMatch(.width, to: .width, of: blueLabel, withMultiplier: 0.6) // The redLabel is positioned below the blueLabel, with its leading edge to its superview, and trailing edge to the greenView - redLabel.autoPinEdge(.Top, toEdge: .Bottom, ofView: blueLabel, withOffset: smallPadding) - redLabel.autoPinEdgeToSuperviewEdge(.Leading, withInset: smallPadding) - redLabel.autoPinEdgeToSuperviewEdge(.Bottom, withInset: largePadding) + redLabel.autoPinEdge(.top, to: .bottom, of: blueLabel, withOffset: smallPadding) + redLabel.autoPinEdge(toSuperviewEdge: .leading, withInset: smallPadding) + redLabel.autoPinEdge(toSuperviewEdge: .bottom, withInset: largePadding) // The greenView is positioned below the blueLabel, with its leading edge to the redLabel, and trailing edge to its superview - greenView.autoPinEdge(.Leading, toEdge: .Trailing, ofView: redLabel, withOffset: largePadding) - greenView.autoPinEdge(.Top, toEdge: .Bottom, ofView: blueLabel, withOffset: smallPadding) - greenView.autoPinEdgeToSuperviewEdge(.Trailing, withInset: smallPadding) + greenView.autoPinEdge(.leading, to: .trailing, of: redLabel, withOffset: largePadding) + greenView.autoPinEdge(.top, to: .bottom, of: blueLabel, withOffset: smallPadding) + greenView.autoPinEdge(toSuperviewEdge: .trailing, withInset: smallPadding) // Match the greenView's height to its width (keeping a consistent aspect ratio) - greenView.autoMatchDimension(.Width, toDimension: .Height, ofView: greenView) + greenView.autoMatch(.width, to: .height, of: greenView) didSetupConstraints = true } diff --git a/PureLayout/Example-iOS/Demos/iOSDemo5ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo5ViewController.swift index eb63cf3..520ba26 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo5ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo5ViewController.swift @@ -13,21 +13,21 @@ import PureLayout class iOSDemo5ViewController: UIViewController { let blueView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .blueColor() - view.layer.borderColor = UIColor.lightGrayColor().CGColor + let view = UIView.newAutoLayout() + view.backgroundColor = .blue + view.layer.borderColor = UIColor.lightGray.cgColor view.layer.borderWidth = 0.5 return view }() let redView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .redColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .red return view }() let purpleLabel: UILabel = { - let label = UILabel.newAutoLayoutView() + let label = UILabel.newAutoLayout() label.backgroundColor = UIColor(red: 1.0, green: 0, blue: 1.0, alpha: 0.3) // semi-transparent purple - label.textColor = .whiteColor() + label.textColor = .white label.text = "The quick brown fox jumps over the lazy dog" return label }() @@ -48,18 +48,18 @@ class iOSDemo5ViewController: UIViewController { override func updateViewConstraints() { if (!didSetupConstraints) { blueView.autoCenterInSuperview() - blueView.autoSetDimensionsToSize(CGSize(width: 150.0, height: 150.0)) + blueView.autoSetDimensions(to: CGSize(width: 150.0, height: 150.0)) // Use a cross-attribute constraint to constrain an ALAxis (Horizontal) to an ALEdge (Bottom) - redView.autoConstrainAttribute(.Horizontal, toAttribute: .Bottom, ofView: blueView) + redView.autoConstrainAttribute(.horizontal, to: .bottom, of: blueView) - redView.autoAlignAxis(.Vertical, toSameAxisOfView: blueView) - redView.autoSetDimensionsToSize(CGSize(width: 50.0, height: 50.0)) + redView.autoAlignAxis(.vertical, toSameAxisOf: blueView) + redView.autoSetDimensions(to: CGSize(width: 50.0, height: 50.0)) // Use another cross-attribute constraint to place the purpleLabel's baseline on the blueView's top edge - purpleLabel.autoConstrainAttribute(.Baseline, toAttribute: .Top, ofView: blueView) + purpleLabel.autoConstrainAttribute(.baseline, to: .top, of: blueView) - purpleLabel.autoAlignAxis(.Vertical, toSameAxisOfView: blueView) + purpleLabel.autoAlignAxis(.vertical, toSameAxisOf: blueView) didSetupConstraints = true } diff --git a/PureLayout/Example-iOS/Demos/iOSDemo6ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo6ViewController.swift index 6328d67..cc49603 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo6ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo6ViewController.swift @@ -13,8 +13,8 @@ import PureLayout class iOSDemo6ViewController: UIViewController { let blueView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .blueColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .blue return view }() @@ -33,19 +33,19 @@ class iOSDemo6ViewController: UIViewController { if (!didSetupConstraints) { // Center the blueView in its superview, and match its width to its height blueView.autoCenterInSuperview() - blueView.autoMatchDimension(.Width, toDimension: .Height, ofView: blueView) + blueView.autoMatch(.width, to: .height, of: blueView) // Make sure the blueView is always at least 20 pt from any edge - blueView.autoPinToTopLayoutGuideOfViewController(self, withInset: 20.0, relation: .GreaterThanOrEqual) - blueView.autoPinToBottomLayoutGuideOfViewController(self, withInset: 20.0, relation: .GreaterThanOrEqual) - blueView.autoPinEdgeToSuperviewEdge(.Left, withInset: 20.0, relation: .GreaterThanOrEqual) - blueView.autoPinEdgeToSuperviewEdge(.Right, withInset: 20.0, relation: .GreaterThanOrEqual) + blueView.autoPin(toTopLayoutGuideOf: self, withInset: 20.0, relation: .greaterThanOrEqual) + blueView.autoPin(toBottomLayoutGuideOf: self, withInset: 20.0, relation: .greaterThanOrEqual) + blueView.autoPinEdge(toSuperviewEdge: .left, withInset: 20.0, relation: .greaterThanOrEqual) + blueView.autoPinEdge(toSuperviewEdge: .right, withInset: 20.0, relation: .greaterThanOrEqual) // Add constraints that set the size of the blueView to a ridiculously large size, but set the priority of these constraints // to a lower value than Required. This allows the Auto Layout solver to let these constraints be broken if one or both of // them conflict with higher-priority constraint(s), such as the above 4 edge constraints. NSLayoutConstraint.autoSetPriority(UILayoutPriorityDefaultHigh) { - self.blueView.autoSetDimensionsToSize(CGSize(width: 10000.0, height: 10000.0)) + self.blueView.autoSetDimensions(to: CGSize(width: 10000.0, height: 10000.0)) } didSetupConstraints = true diff --git a/PureLayout/Example-iOS/Demos/iOSDemo7ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo7ViewController.swift index 22f6a4f..b59294f 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo7ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo7ViewController.swift @@ -13,13 +13,13 @@ import PureLayout class iOSDemo7ViewController: UIViewController { let blueView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .blueColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .blue return view }() let redView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .redColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .red return view }() @@ -42,7 +42,7 @@ class iOSDemo7ViewController: UIViewController { view.setNeedsUpdateConstraints() // bootstrap Auto Layout } - override func viewDidAppear(animated: Bool) { + override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) /** @@ -61,15 +61,15 @@ class iOSDemo7ViewController: UIViewController { // Remember, this code is just the initial constraint setup which only happens the first time this method is called if (!didSetupConstraints) { - blueView.autoPinToTopLayoutGuideOfViewController(self, withInset: 20.0) - blueView.autoAlignAxisToSuperviewAxis(.Vertical) + blueView.autoPin(toTopLayoutGuideOf: self, withInset: 20.0) + blueView.autoAlignAxis(toSuperviewAxis: .vertical) - blueView.autoSetDimension(.Width, toSize: 50.0) - blueViewHeightConstraint = blueView.autoSetDimension(.Height, toSize: blueViewInitialHeight) + blueView.autoSetDimension(.width, toSize: 50.0) + blueViewHeightConstraint = blueView.autoSetDimension(.height, toSize: blueViewInitialHeight) - redView.autoSetDimension(.Height, toSize: 50.0) - redView.autoMatchDimension(.Width, toDimension: .Height, ofView: blueView, withMultiplier: 1.5) - redView.autoAlignAxisToSuperviewAxis(.Vertical) + redView.autoSetDimension(.height, toSize: 50.0) + redView.autoMatch(.width, to: .height, of: blueView, withMultiplier: 1.5) + redView.autoAlignAxis(toSuperviewAxis: .vertical) didSetupConstraints = true } @@ -80,10 +80,10 @@ class iOSDemo7ViewController: UIViewController { redViewEdgeConstraint?.autoRemove() if isAnimatingToEndState { blueViewHeightConstraint?.constant = blueViewEndHeight - redViewEdgeConstraint = redView.autoPinEdgeToSuperviewEdge(.Bottom, withInset: 150.0) + redViewEdgeConstraint = redView.autoPinEdge(toSuperviewEdge: .bottom, withInset: 150.0) } else { blueViewHeightConstraint?.constant = blueViewInitialHeight - redViewEdgeConstraint = redView.autoPinEdge(.Top, toEdge: .Bottom, ofView: blueView, withOffset: 20.0) + redViewEdgeConstraint = redView.autoPinEdge(.top, to: .bottom, of: blueView, withOffset: 20.0) } super.updateViewConstraints() @@ -96,7 +96,7 @@ class iOSDemo7ViewController: UIViewController { view.setNeedsUpdateConstraints() view.updateConstraintsIfNeeded() - UIView.animateWithDuration(1.0, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: UIViewAnimationOptions(), + UIView.animate(withDuration: 1.0, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: UIViewAnimationOptions(), animations: { self.view.layoutIfNeeded() }, @@ -116,7 +116,7 @@ class iOSDemo7ViewController: UIViewController { view.setNeedsUpdateConstraints() view.updateConstraintsIfNeeded() - UIView.animateWithDuration(1.0, delay: 0, options: UIViewAnimationOptions(), + UIView.animate(withDuration: 1.0, delay: 0, options: UIViewAnimationOptions(), animations: { self.view.layoutIfNeeded() }, diff --git a/PureLayout/Example-iOS/Demos/iOSDemo8ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo8ViewController.swift index 410e8d2..50d3312 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo8ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo8ViewController.swift @@ -13,28 +13,28 @@ import PureLayout class iOSDemo8ViewController: UIViewController { let containerView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .lightGrayColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .lightGray return view }() let blueView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .blueColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .blue return view }() let redView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .redColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .red return view }() let yellowView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .yellowColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .yellow return view }() let greenView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .greenColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .green return view }() @@ -64,22 +64,22 @@ class iOSDemo8ViewController: UIViewController { */ NSLayoutConstraint.autoSetIdentifier("Pin Container View Edges") { - self.containerView.autoPinToTopLayoutGuideOfViewController(self, withInset: 10.0) - self.containerView.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsets(top: 0.0, left: 10.0, bottom: 10.0, right: 10.0), excludingEdge: .Top) + self.containerView.autoPin(toTopLayoutGuideOf: self, withInset: 10.0) + self.containerView.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets(top: 0.0, left: 10.0, bottom: 10.0, right: 10.0), excludingEdge: .top) } let views: NSArray = [redView, blueView, yellowView, greenView] - (views.autoDistributeViewsAlongAxis(.Vertical, alignedTo: .Vertical, withFixedSize: 40.0) as NSArray).autoIdentifyConstraints("Distribute Views Vertically") + (views.autoDistributeViews(along: .vertical, alignedTo: .vertical, withFixedSize: 40.0) as NSArray).autoIdentifyConstraints("Distribute Views Vertically") /** Note that the -autoIdentify and -autoIdentifyConstraints methods set the identifier, and then return the constraint(s). This lets you chain the identifier call right after creating the constraint(s), and still capture a reference to the constraint(s)! */ - let constraints = (views.autoSetViewsDimension(.Width, toSize: 60.0) as NSArray).autoIdentifyConstraints("Set Width of All Views") + let constraints = (views.autoSetViewsDimension(.width, toSize: 60.0) as NSArray).autoIdentifyConstraints("Set Width of All Views") print("Just added \(constraints.count) constraints!") // you can do something with the constraints at this point - let constraint = redView.autoAlignAxisToSuperviewAxis(.Vertical).autoIdentify("Align Red View to Superview Vertical Axis") + let constraint = redView.autoAlignAxis(toSuperviewAxis: .vertical).autoIdentify("Align Red View to Superview Vertical Axis") print("Just added one constraint with the identifier: \(constraint.identifier)") // you can do something with the constraint at this point /** diff --git a/PureLayout/Example-iOS/Demos/iOSDemo9ViewController.swift b/PureLayout/Example-iOS/Demos/iOSDemo9ViewController.swift index d32a203..89718e3 100644 --- a/PureLayout/Example-iOS/Demos/iOSDemo9ViewController.swift +++ b/PureLayout/Example-iOS/Demos/iOSDemo9ViewController.swift @@ -13,23 +13,23 @@ import PureLayout class iOSDemo9ViewController: UIViewController { let blueView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .blueColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .blue return view }() let redView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .redColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .red return view }() let yellowView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .yellowColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .yellow return view }() let greenView: UIView = { - let view = UIView.newAutoLayoutView() - view.backgroundColor = .greenColor() + let view = UIView.newAutoLayout() + view.backgroundColor = .green return view }() @@ -50,8 +50,8 @@ class iOSDemo9ViewController: UIViewController { override func updateViewConstraints() { if (!didSetupConstraints) { // Before layout margins were introduced, this is a typical way of giving a subview some padding from its superview's edges - blueView.autoPinToTopLayoutGuideOfViewController(self, withInset: 10.0) - blueView.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsets(top: 0, left: 10.0, bottom: 10.0, right: 10.0), excludingEdge: .Top) + blueView.autoPin(toTopLayoutGuideOf: self, withInset: 10.0) + blueView.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets(top: 0, left: 10.0, bottom: 10.0, right: 10.0), excludingEdge: .top) // Set the layoutMargins of the blueView, which will have an effect on subviews of the blueView that attach to // the blueView's margin attributes -- in this case, the redView @@ -61,19 +61,19 @@ class iOSDemo9ViewController: UIViewController { // Let the redView inherit the values we just set for the blueView's layoutMargins by setting the below property to YES. // Then, pin the yellowView's edges to the redView's margins, giving the yellowView the same insets from its superview as the redView. redView.preservesSuperviewLayoutMargins = true - yellowView.autoPinEdgeToSuperviewMargin(.Left) - yellowView.autoPinEdgeToSuperviewMargin(.Right) + yellowView.autoPinEdge(toSuperviewMargin: .left) + yellowView.autoPinEdge(toSuperviewMargin: .right) - // By aligning the yellowView to its superview's horiztonal margin axis, the yellowView will be positioned with its horizontal axis + // By aligning the yellowView to its superview's horizontal margin axis, the yellowView will be positioned with its horizontal axis // in the middle of the redView's top and bottom margins (causing it to be slightly closer to the top of the redView, since the // redView has a much larger bottom margin than top margin). - yellowView.autoAlignAxisToSuperviewMarginAxis(.Horizontal) - yellowView.autoMatchDimension(.Height, toDimension: .Height, ofView: redView, withMultiplier: 0.5) + yellowView.autoAlignAxis(toSuperviewMarginAxis: .horizontal) + yellowView.autoMatch(.height, to: .height, of: redView, withMultiplier: 0.5) // Since yellowView.preservesSuperviewLayoutMargins is NO by default, it will not preserve (inherit) its superview's margins, // and instead will just have the default margins of: {8.0, 8.0, 8.0, 8.0} which will apply to its subviews (greenView) - greenView.autoPinEdgesToSuperviewMarginsExcludingEdge(.Bottom) - greenView.autoSetDimension(.Height, toSize: 50.0) + greenView.autoPinEdges(toSuperviewMarginsExcludingEdge: .bottom) + greenView.autoSetDimension(.height, toSize: 50.0) didSetupConstraints = true } diff --git a/PureLayout/Example-iOS/Images-iOS.xcassets/AppIcon.appiconset/Contents.json b/PureLayout/Example-iOS/Images-iOS.xcassets/AppIcon.appiconset/Contents.json index 4a05111..13cb236 100644 --- a/PureLayout/Example-iOS/Images-iOS.xcassets/AppIcon.appiconset/Contents.json +++ b/PureLayout/Example-iOS/Images-iOS.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", @@ -45,6 +55,16 @@ "size" : "60x60", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "idiom" : "ipad", "size" : "29x29", @@ -99,6 +119,11 @@ "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/PureLayout/Example-iOS/Images-iOS.xcassets/LaunchImage.launchimage/Contents.json b/PureLayout/Example-iOS/Images-iOS.xcassets/LaunchImage.launchimage/Contents.json index 729a5e1..988f966 100644 --- a/PureLayout/Example-iOS/Images-iOS.xcassets/LaunchImage.launchimage/Contents.json +++ b/PureLayout/Example-iOS/Images-iOS.xcassets/LaunchImage.launchimage/Contents.json @@ -1,5 +1,23 @@ { "images" : [ + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "2436h", + "filename" : "iPhone_X_Portrait.png", + "minimum-system-version" : "11.0", + "orientation" : "portrait", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "2436h", + "filename" : "iPhone_X_Landscape.png", + "minimum-system-version" : "11.0", + "orientation" : "landscape", + "scale" : "3x" + }, { "extent" : "full-screen", "idiom" : "iphone", diff --git a/PureLayout/Example-iOS/Images-iOS.xcassets/LaunchImage.launchimage/iPhone_X_Landscape.png b/PureLayout/Example-iOS/Images-iOS.xcassets/LaunchImage.launchimage/iPhone_X_Landscape.png new file mode 100644 index 0000000..2ba5452 Binary files /dev/null and b/PureLayout/Example-iOS/Images-iOS.xcassets/LaunchImage.launchimage/iPhone_X_Landscape.png differ diff --git a/PureLayout/Example-iOS/Images-iOS.xcassets/LaunchImage.launchimage/iPhone_X_Portrait.png b/PureLayout/Example-iOS/Images-iOS.xcassets/LaunchImage.launchimage/iPhone_X_Portrait.png new file mode 100644 index 0000000..f91fe5d Binary files /dev/null and b/PureLayout/Example-iOS/Images-iOS.xcassets/LaunchImage.launchimage/iPhone_X_Portrait.png differ diff --git a/PureLayout/Example-tvOS/TVApp.swift b/PureLayout/Example-tvOS/TVApp.swift index a0f3651..642ace5 100644 --- a/PureLayout/Example-tvOS/TVApp.swift +++ b/PureLayout/Example-tvOS/TVApp.swift @@ -14,15 +14,15 @@ class TVViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - let views = [UIColor.redColor(), UIColor.greenColor(), UIColor.blueColor()] + let views = [UIColor.red, UIColor.green, UIColor.blue] .map(TVButton.init) views.forEach(self.view.addSubview) - (views as NSArray).autoDistributeViewsAlongAxis(.Horizontal, alignedTo: .Horizontal, withFixedSpacing: 50) + (views as NSArray).autoDistributeViews(along: .horizontal, alignedTo: .horizontal, withFixedSpacing: 50) views.forEach { view in - view.autoAlignAxisToSuperviewAxis(.Horizontal) - view.autoSetDimension(.Height, toSize: 300) + view.autoAlignAxis(toSuperviewAxis: .horizontal) + view.autoSetDimension(.height, toSize: 300) } } } @@ -34,7 +34,7 @@ class TVAppDelegate: UIResponder, UIApplicationDelegate { class TVButton : UIControl { required init(color: UIColor) { - super.init(frame: CGRectZero) + super.init(frame: CGRect.zero) self.translatesAutoresizingMaskIntoConstraints = false self.backgroundColor = color } diff --git a/PureLayout/PureLayout.xcodeproj/project.pbxproj b/PureLayout/PureLayout.xcodeproj/project.pbxproj index 434a3db..acaa292 100644 --- a/PureLayout/PureLayout.xcodeproj/project.pbxproj +++ b/PureLayout/PureLayout.xcodeproj/project.pbxproj @@ -19,7 +19,6 @@ 164C8B7C1C0D36500007A6B1 /* PureLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = B1046A8C1A7F2C700017187F /* PureLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; 164C8B7D1C0D36500007A6B1 /* PureLayout+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B1046A8A1A7F2C700017187F /* PureLayout+Internal.h */; settings = {ATTRIBUTES = (Private, ); }; }; 164C8B7E1C0D36500007A6B1 /* PureLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = B1046A8B1A7F2C700017187F /* PureLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 164C8B8B1C0D37BF0007A6B1 /* PureLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 164C8B831C0D36500007A6B1 /* PureLayout.framework */; }; 164C8B8C1C0D37C70007A6B1 /* PureLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 164C8B831C0D36500007A6B1 /* PureLayout.framework */; }; 164C8B8D1C0D37C70007A6B1 /* PureLayout.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 164C8B831C0D36500007A6B1 /* PureLayout.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 567E6C881C4125C60031B78F /* ALiOSDemo11ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 567E6C861C4125C60031B78F /* ALiOSDemo11ViewController.m */; }; @@ -146,6 +145,13 @@ remoteGlobalIDString = 164C8B721C0D36500007A6B1; remoteInfo = PureLayout_tvOS; }; + 6D207E9A1E2E99EB00CCDD7C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B12C23D317C3FDE4001CF667 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B1A290DA19562FDA00D4765E; + remoteInfo = "Example-Mac"; + }; A7D496571B7B084800A74818 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B12C23D317C3FDE4001CF667 /* Project object */; @@ -174,13 +180,6 @@ remoteGlobalIDString = B12C23DA17C3FDE4001CF667; remoteInfo = "Example-iOS"; }; - B1046B1B1A7F4A680017187F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = B12C23D317C3FDE4001CF667 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B1A290DA19562FDA00D4765E; - remoteInfo = "Example-Mac"; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -262,15 +261,15 @@ B1006C6E19E76D4200B92767 /* ALiOSDemo1ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ALiOSDemo1ViewController.h; path = "Example-iOS/Demos/ALiOSDemo1ViewController.h"; sourceTree = SOURCE_ROOT; }; B1006C6F19E76D4200B92767 /* ALiOSDemo1ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ALiOSDemo1ViewController.m; path = "Example-iOS/Demos/ALiOSDemo1ViewController.m"; sourceTree = SOURCE_ROOT; }; B1046A801A7F29F80017187F /* PureLayoutDistributeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PureLayoutDistributeTests.m; path = PureLayoutTests/PureLayoutDistributeTests.m; sourceTree = ""; }; - B1046A841A7F2C700017187F /* ALView+PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ALView+PureLayout.h"; path = "PureLayout/ALView+PureLayout.h"; sourceTree = ""; }; + B1046A841A7F2C700017187F /* ALView+PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ALView+PureLayout.h"; path = "PureLayout/include/ALView+PureLayout.h"; sourceTree = ""; }; B1046A851A7F2C700017187F /* ALView+PureLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "ALView+PureLayout.m"; path = "PureLayout/ALView+PureLayout.m"; sourceTree = ""; }; - B1046A861A7F2C700017187F /* NSArray+PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+PureLayout.h"; path = "PureLayout/NSArray+PureLayout.h"; sourceTree = ""; }; + B1046A861A7F2C700017187F /* NSArray+PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+PureLayout.h"; path = "PureLayout/include/NSArray+PureLayout.h"; sourceTree = ""; }; B1046A871A7F2C700017187F /* NSArray+PureLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+PureLayout.m"; path = "PureLayout/NSArray+PureLayout.m"; sourceTree = ""; }; - B1046A881A7F2C700017187F /* NSLayoutConstraint+PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSLayoutConstraint+PureLayout.h"; path = "PureLayout/NSLayoutConstraint+PureLayout.h"; sourceTree = ""; }; + B1046A881A7F2C700017187F /* NSLayoutConstraint+PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSLayoutConstraint+PureLayout.h"; path = "PureLayout/include/NSLayoutConstraint+PureLayout.h"; sourceTree = ""; }; B1046A891A7F2C700017187F /* NSLayoutConstraint+PureLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSLayoutConstraint+PureLayout.m"; path = "PureLayout/NSLayoutConstraint+PureLayout.m"; sourceTree = ""; }; B1046A8A1A7F2C700017187F /* PureLayout+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "PureLayout+Internal.h"; path = "PureLayout/PureLayout+Internal.h"; sourceTree = ""; }; - B1046A8B1A7F2C700017187F /* PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PureLayout.h; path = PureLayout/PureLayout.h; sourceTree = ""; }; - B1046A8C1A7F2C700017187F /* PureLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PureLayoutDefines.h; path = PureLayout/PureLayoutDefines.h; sourceTree = ""; }; + B1046A8B1A7F2C700017187F /* PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PureLayout.h; path = PureLayout/include/PureLayout.h; sourceTree = ""; }; + B1046A8C1A7F2C700017187F /* PureLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PureLayoutDefines.h; path = PureLayout/include/PureLayoutDefines.h; sourceTree = ""; }; B1046A9B1A7F2CDA0017187F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = InfoPlist.strings; sourceTree = ""; }; B1046A9D1A7F2CE80017187F /* PureLayoutTests-Mac-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "PureLayoutTests-Mac-Info.plist"; path = "PureLayoutTests/PureLayoutTests-Mac/PureLayoutTests-Mac-Info.plist"; sourceTree = SOURCE_ROOT; }; B1046AA11A7F2D1B0017187F /* PureLayoutTests-Mac-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "PureLayoutTests-Mac-Prefix.pch"; path = "PureLayoutTests/PureLayoutTests-Mac/PureLayoutTests-Mac-Prefix.pch"; sourceTree = SOURCE_ROOT; }; @@ -342,7 +341,6 @@ buildActionMask = 2147483647; files = ( 164C8B8C1C0D37C70007A6B1 /* PureLayout.framework in Frameworks */, - 164C8B8B1C0D37BF0007A6B1 /* PureLayout.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -605,8 +603,7 @@ B125489319C29D2A00DDD7BF /* Images-iOS.xcassets */, B12C23E517C3FDE4001CF667 /* Supporting Files */, ); - name = "Example-iOS"; - path = Example; + path = "Example-iOS"; sourceTree = ""; }; B12C23E517C3FDE4001CF667 /* Supporting Files */ = { @@ -672,7 +669,8 @@ B1046AA21A7F2D520017187F /* PureLayoutPriorityTests-iOS.m */, B1EC8563195662790099293C /* Supporting Files */, ); - path = "PureLayoutTests-iOS"; + name = "PureLayoutTests-iOS"; + path = "PureLayoutTests/PureLayoutTests-iOS"; sourceTree = ""; }; B1EC8563195662790099293C /* Supporting Files */ = { @@ -690,7 +688,8 @@ children = ( B1EC857F195662B40099293C /* Supporting Files */, ); - path = "PureLayoutTests-Mac"; + name = "PureLayoutTests-Mac"; + path = "PureLayoutTests/PureLayoutTests-Mac"; sourceTree = ""; }; B1EC857F195662B40099293C /* Supporting Files */ = { @@ -907,7 +906,7 @@ buildRules = ( ); dependencies = ( - B1046B1C1A7F4A680017187F /* PBXTargetDependency */, + 6D207E9B1E2E99EB00CCDD7C /* PBXTargetDependency */, ); name = "PureLayoutTests-Mac"; productName = "PureLayoutTests-Mac"; @@ -922,24 +921,43 @@ attributes = { CLASSPREFIX = AL; LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0700; + LastUpgradeCheck = 1000; TargetAttributes = { 164C8B4D1C0D354E0007A6B1 = { CreatedOnToolsVersion = 7.1; + LastSwiftMigration = 0800; + ProvisioningStyle = Manual; + }; + 164C8B721C0D36500007A6B1 = { + LastSwiftMigration = 0800; + ProvisioningStyle = Manual; + }; + A7D496551B7B084800A74818 = { + LastSwiftMigration = 0800; + ProvisioningStyle = Manual; }; B1046AAF1A7F32380017187F = { CreatedOnToolsVersion = 6.1.1; + LastSwiftMigration = 0800; + ProvisioningStyle = Manual; }; B1046AD71A7F32790017187F = { CreatedOnToolsVersion = 6.1.1; }; + B12C23DA17C3FDE4001CF667 = { + LastSwiftMigration = 0800; + ProvisioningStyle = Manual; + }; B1A290DA19562FDA00D4765E = { CreatedOnToolsVersion = 6.0; }; B1EC855C195662790099293C = { + LastSwiftMigration = 0800; + ProvisioningStyle = Manual; TestTargetID = B12C23DA17C3FDE4001CF667; }; B1EC857B195662B40099293C = { + ProvisioningStyle = Manual; TestTargetID = B1A290DA19562FDA00D4765E; }; }; @@ -949,6 +967,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ar, Base, @@ -1201,6 +1220,11 @@ target = 164C8B721C0D36500007A6B1 /* PureLayout_tvOS */; targetProxy = 164C8B8E1C0D37C70007A6B1 /* PBXContainerItemProxy */; }; + 6D207E9B1E2E99EB00CCDD7C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B1A290DA19562FDA00D4765E /* Example-Mac */; + targetProxy = 6D207E9A1E2E99EB00CCDD7C /* PBXContainerItemProxy */; + }; A7D496561B7B084800A74818 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B1046AAF1A7F32380017187F /* PureLayout_iOS */; @@ -1221,11 +1245,6 @@ target = B12C23DA17C3FDE4001CF667 /* Example-iOS */; targetProxy = B1046B191A7F4A640017187F /* PBXContainerItemProxy */; }; - B1046B1C1A7F4A680017187F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B1A290DA19562FDA00D4765E /* Example-Mac */; - targetProxy = B1046B1B1A7F4A680017187F /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -1301,6 +1320,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -1315,6 +1335,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1331,6 +1352,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -1345,6 +1367,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.Example-tvOS"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1358,8 +1381,11 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -1379,9 +1405,10 @@ MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = PureLayout; + SDKROOT = appletvos; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "appletvsimulator appletvos"; - TARGETED_DEVICE_FAMILY = "1,2"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1396,8 +1423,11 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -1414,9 +1444,10 @@ MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = PureLayout; + SDKROOT = appletvos; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "appletvsimulator appletvos"; - TARGETED_DEVICE_FAMILY = "1,2"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1429,6 +1460,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; + DEVELOPMENT_TEAM = ""; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", "USING_XCODE7_SCHEME=1", @@ -1440,6 +1472,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Example-iOS/Example-iOS-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; @@ -1451,6 +1484,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; + DEVELOPMENT_TEAM = ""; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", "USING_XCODE7_SCHEME=1", @@ -1461,6 +1495,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Example-iOS/Example-iOS-Bridging-Header.h"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; @@ -1469,13 +1504,17 @@ B1046ACA1A7F32390017187F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -1497,6 +1536,7 @@ PRODUCT_NAME = PureLayout; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1506,13 +1546,17 @@ B1046ACB1A7F32390017187F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -1530,6 +1574,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = PureLayout; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1544,7 +1589,6 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; @@ -1568,6 +1612,8 @@ MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = PureLayout; + PROVISIONING_PROFILE = None; + PROVISIONING_PROFILE_SPECIFIER = None; SDKROOT = macosx; SKIP_INSTALL = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -1583,7 +1629,6 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -1605,6 +1650,8 @@ MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = PureLayout; + PROVISIONING_PROFILE = None; + PROVISIONING_PROFILE_SPECIFIER = None; SDKROOT = macosx; SKIP_INSTALL = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -1616,33 +1663,52 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_GENERATE_TEST_COVERAGE_FILES = YES; GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.7; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; WARNING_CFLAGS = "-Wreserved-id-macro"; @@ -1653,25 +1719,45 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.7; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; VALIDATE_PRODUCT = YES; WARNING_CFLAGS = "-Wreserved-id-macro"; }; @@ -1683,6 +1769,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "Example-iOS/Example-iOS-Info.plist"; INFOPLIST_OUTPUT_FORMAT = "same-as-input"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1690,6 +1777,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Example-iOS/Example-iOS-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; @@ -1701,12 +1789,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "Example-iOS/Example-iOS-Info.plist"; INFOPLIST_OUTPUT_FORMAT = "same-as-input"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Example-iOS/Example-iOS-Bridging-Header.h"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; @@ -1721,7 +1811,6 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -1738,6 +1827,8 @@ METAL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = None; + PROVISIONING_PROFILE_SPECIFIER = None; SDKROOT = macosx; }; name = Debug; @@ -1751,7 +1842,6 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; @@ -1766,6 +1856,8 @@ METAL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = None; + PROVISIONING_PROFILE_SPECIFIER = None; SDKROOT = macosx; }; name = Release; @@ -1777,8 +1869,9 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); @@ -1796,7 +1889,9 @@ INFOPLIST_FILE = "PureLayoutTests/PureLayoutTests-iOS/PureLayoutTests-iOS-Info.plist"; PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-iOS.app/Example-iOS"; + WARNING_CFLAGS = ""; WRAPPER_EXTENSION = xctest; }; name = Debug; @@ -1808,9 +1903,10 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + DEVELOPMENT_TEAM = ""; ENABLE_NS_ASSERTIONS = NO; FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); @@ -1824,7 +1920,9 @@ INFOPLIST_FILE = "PureLayoutTests/PureLayoutTests-iOS/PureLayoutTests-iOS-Info.plist"; PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-iOS.app/Example-iOS"; + WARNING_CFLAGS = ""; WRAPPER_EXTENSION = xctest; }; name = Release; @@ -1836,7 +1934,9 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_FRAMEWORKS_DIR)", "$(inherited)", @@ -1857,8 +1957,9 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; - SUPPORTED_PLATFORMS = "appletvsimulator appletvos"; + SUPPORTED_PLATFORMS = macosx; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-Mac.app/Contents/MacOS/Example-Mac"; + WARNING_CFLAGS = ""; WRAPPER_EXTENSION = xctest; }; name = Debug; @@ -1870,8 +1971,10 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; ENABLE_NS_ASSERTIONS = NO; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_FRAMEWORKS_DIR)", @@ -1889,8 +1992,9 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.PureLayout.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; - SUPPORTED_PLATFORMS = "appletvsimulator appletvos"; + SUPPORTED_PLATFORMS = macosx; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-Mac.app/Contents/MacOS/Example-Mac"; + WARNING_CFLAGS = ""; WRAPPER_EXTENSION = xctest; }; name = Release; diff --git a/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-Mac.xcscheme b/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-Mac.xcscheme index e4ba26c..0523542 100644 --- a/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-Mac.xcscheme +++ b/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-Mac.xcscheme @@ -1,6 +1,6 @@ + codeCoverageEnabled = "YES" + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -52,11 +53,11 @@ diff --git a/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-iOS-Xcode7.xcscheme b/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-iOS-Xcode7.xcscheme index 2f2a853..4f07a88 100644 --- a/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-iOS-Xcode7.xcscheme +++ b/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-iOS-Xcode7.xcscheme @@ -1,6 +1,6 @@ diff --git a/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme b/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme index 2e11f4d..d32cfb5 100644 --- a/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme +++ b/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme @@ -1,6 +1,6 @@ + codeCoverageEnabled = "YES" + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -66,11 +67,11 @@ diff --git a/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme b/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme index 51c05e8..b09a7d3 100644 --- a/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme +++ b/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme @@ -1,6 +1,6 @@ diff --git a/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/PureLayout_Mac.xcscheme b/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/PureLayout_Mac.xcscheme index e7b26a9..9d1f458 100644 --- a/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/PureLayout_Mac.xcscheme +++ b/PureLayout/PureLayout.xcodeproj/xcshareddata/xcschemes/PureLayout_Mac.xcscheme @@ -1,6 +1,6 @@ + codeCoverageEnabled = "YES" + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -52,11 +53,11 @@ + codeCoverageEnabled = "YES" + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -52,11 +53,11 @@ @@ -51,6 +52,15 @@ debugDocumentVersioning = "YES" debugServiceExtension = "internal" allowLocationSimulation = "YES"> + + + + diff --git a/PureLayout/PureLayout/ALView+PureLayout.m b/PureLayout/PureLayout/ALView+PureLayout.m index 15d01b5..3ec32e2 100755 --- a/PureLayout/PureLayout/ALView+PureLayout.m +++ b/PureLayout/PureLayout/ALView+PureLayout.m @@ -80,7 +80,7 @@ - (instancetype)configureForAutoLayout */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoCenterInSuperview { - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; [constraints addObject:[self autoAlignAxisToSuperviewAxis:ALAxisHorizontal]]; [constraints addObject:[self autoAlignAxisToSuperviewAxis:ALAxisVertical]]; return constraints; @@ -109,7 +109,7 @@ - (NSLayoutConstraint *)autoAlignAxisToSuperviewAxis:(ALAxis)axis */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoCenterInSuperviewMargins { - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; [constraints addObject:[self autoAlignAxisToSuperviewMarginAxis:ALAxisHorizontal]]; [constraints addObject:[self autoAlignAxisToSuperviewMarginAxis:ALAxisVertical]]; return constraints; @@ -133,6 +133,234 @@ - (NSLayoutConstraint *)autoAlignAxisToSuperviewMarginAxis:(ALAxis)axis #endif /* PL__PureLayout_MinBaseSDK_iOS_8_0 */ +#pragma mark Pin Edges to SafeArea + +#if TARGET_OS_IPHONE + +/** + Pins the given edge of the view to the same edge of its superview anchor. + + @param edge The edge of this view and its superview to pin. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewSafeArea:(ALEdge)edge +{ + return [self autoPinEdgeToSuperviewSafeArea:edge withInset:0.0]; +} + +/** + Pins the given edge of the view to the same edge of its superview anchor with an inset. + + @param edge The edge of this view and its superview to pin. + @param inset The amount to inset this view's edge from the superview's edge. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewSafeArea:(ALEdge)edge withInset:(CGFloat)inset +{ + return [self autoPinEdgeToSuperviewSafeArea:edge withInset:inset relation:NSLayoutRelationEqual]; +} + +/** + Pins the given edge of the view to the same edge of its superview anchor/edge with an inset as a maximum or minimum. + + @param edge The edge of this view and its superview to pin. + @param inset The amount to inset this view's edge from the superview's edge. + @param relation Whether the inset should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewSafeArea:(ALEdge)edge withInset:(CGFloat)inset relation:(NSLayoutRelation)relation +{ +#if PL__PureLayout_MinBaseSDK_iOS_9_0 + self.translatesAutoresizingMaskIntoConstraints = NO; + + ALView *superview = self.superview; + NSAssert(superview, @"View's superview must not be nil.\nView: %@", self); + NSLayoutConstraint *constraint = nil; + NSLayoutYAxisAnchor *topAnchor; + NSLayoutYAxisAnchor *bottomAnchor; + NSLayoutXAxisAnchor *leftAnchor; + NSLayoutXAxisAnchor *rightAnchor; + NSLayoutXAxisAnchor *leadingAnchor; + NSLayoutXAxisAnchor *trailingAnchor; + +#if PL__PureLayout_MinBaseSDK_iOS_11_0 // only iOS/tvOS SDK 11.0 has @available syntax introduced + if (@available(iOS 11.0, tvOS 11.0, *)) { + topAnchor = superview.safeAreaLayoutGuide.topAnchor; + bottomAnchor = superview.safeAreaLayoutGuide.bottomAnchor; + leftAnchor = superview.safeAreaLayoutGuide.leftAnchor; + rightAnchor = superview.safeAreaLayoutGuide.rightAnchor; + leadingAnchor = superview.safeAreaLayoutGuide.leadingAnchor; + trailingAnchor = superview.safeAreaLayoutGuide.trailingAnchor; + } else if (@available(iOS 9.0, *)) { + topAnchor = superview.topAnchor; + bottomAnchor = superview.bottomAnchor; + leftAnchor = superview.leftAnchor; + rightAnchor = superview.rightAnchor; + leadingAnchor = superview.leadingAnchor; + trailingAnchor = superview.trailingAnchor; + } else { // for targeting iOS 8 or below without anchor system + return [self autoPinEdgeToSuperviewEdge:edge withInset:inset relation:relation]; + } +#elif PL__PureLayout_MinBaseSDK_iOS_9_0 // fallback to older SDKs, when using Xcode 8.0, which only has iOS SDK 10.0 + if (PL__PureLayout_MinSysVer_iOS_9_0) { + topAnchor = superview.topAnchor; + bottomAnchor = superview.bottomAnchor; + leftAnchor = superview.leftAnchor; + rightAnchor = superview.rightAnchor; + leadingAnchor = superview.leadingAnchor; + trailingAnchor = superview.trailingAnchor; + } else { // for targeting iOS 8 or below without anchor system + return [self autoPinEdgeToSuperviewEdge:edge withInset:inset relation:relation]; + } +#endif + if (edge == ALEdgeBottom || edge == ALEdgeRight || edge == ALEdgeTrailing) { + // The bottom, right, and trailing insets (and relations, if an inequality) are inverted to become offsets + inset = -inset; + } + switch (edge) { + case ALEdgeLeft: + switch (relation) { + case NSLayoutRelationEqual: + constraint = [[self leftAnchor] constraintEqualToAnchor:leftAnchor constant:inset]; + break; + case NSLayoutRelationLessThanOrEqual: + constraint = [[self leftAnchor] constraintLessThanOrEqualToAnchor:leftAnchor constant:inset]; + break; + case NSLayoutRelationGreaterThanOrEqual: + constraint = [[self leftAnchor] constraintGreaterThanOrEqualToAnchor:leftAnchor constant:inset]; + break; + } + break; + case ALEdgeRight: + switch (relation) { + case NSLayoutRelationEqual: + constraint = [[self rightAnchor] constraintEqualToAnchor:rightAnchor constant:inset]; + break; + case NSLayoutRelationLessThanOrEqual: + constraint = [[self rightAnchor] constraintGreaterThanOrEqualToAnchor:rightAnchor constant:inset]; + break; + case NSLayoutRelationGreaterThanOrEqual: + constraint = [[self rightAnchor] constraintLessThanOrEqualToAnchor:rightAnchor constant:inset]; + break; + } + break; + case ALEdgeTop: + switch (relation) { + case NSLayoutRelationEqual: + constraint = [[self topAnchor] constraintEqualToAnchor:topAnchor constant:inset]; + break; + case NSLayoutRelationLessThanOrEqual: + constraint = [[self topAnchor] constraintLessThanOrEqualToAnchor:topAnchor constant:inset]; + break; + case NSLayoutRelationGreaterThanOrEqual: + constraint = [[self topAnchor] constraintGreaterThanOrEqualToAnchor:topAnchor constant:inset]; + break; + } + break; + case ALEdgeBottom: + switch (relation) { + case NSLayoutRelationEqual: + constraint = [[self bottomAnchor] constraintEqualToAnchor:bottomAnchor constant:inset]; + break; + case NSLayoutRelationLessThanOrEqual: + constraint = [[self bottomAnchor] constraintGreaterThanOrEqualToAnchor:bottomAnchor constant:inset]; + break; + case NSLayoutRelationGreaterThanOrEqual: + constraint = [[self bottomAnchor] constraintLessThanOrEqualToAnchor:bottomAnchor constant:inset]; + break; + } + break; + case ALEdgeLeading: + switch (relation) { + case NSLayoutRelationEqual: + constraint = [[self leadingAnchor] constraintEqualToAnchor:leadingAnchor constant:inset]; + break; + case NSLayoutRelationLessThanOrEqual: + constraint = [[self leadingAnchor] constraintLessThanOrEqualToAnchor:leadingAnchor constant:inset]; + break; + case NSLayoutRelationGreaterThanOrEqual: + constraint = [[self leadingAnchor] constraintGreaterThanOrEqualToAnchor:leadingAnchor constant:inset]; + break; + } + break; + case ALEdgeTrailing: + switch (relation) { + case NSLayoutRelationEqual: + constraint = [[self trailingAnchor] constraintEqualToAnchor:trailingAnchor constant:inset]; + break; + case NSLayoutRelationLessThanOrEqual: + constraint = [[self trailingAnchor] constraintGreaterThanOrEqualToAnchor:trailingAnchor constant:inset]; + break; + case NSLayoutRelationGreaterThanOrEqual: + constraint = [[self trailingAnchor] constraintLessThanOrEqualToAnchor:trailingAnchor constant:inset]; + break; + } + break; + } + [constraint autoInstall]; + return constraint; +#else + return [self autoPinEdgeToSuperviewEdge:edge withInset:inset relation:relation]; +#endif /* PL__PureLayout_MinBaseSDK_iOS_9_0 */ +} + +/** + Pins the edges of the view to the edges of its superview anchor. + + @return An array of constraints added, ordered counterclockwise from top. + */ +- (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewSafeArea +{ + return [self autoPinEdgesToSuperviewSafeAreaWithInsets:ALEdgeInsetsZero]; +} + +/** + Pins the edges of the view to the edges of its superview anchor with the given edge insets. + The insets.left corresponds to a leading edge constraint, and insets.right corresponds to a trailing edge constraint. + + @param insets The insets for this view's edges from its superview's edges. + @return An array of constraints added, ordered counterclockwise from top. + */ +- (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewSafeAreaWithInsets:(ALEdgeInsets)insets +{ + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + [constraints addObject:[self autoPinEdgeToSuperviewSafeArea:ALEdgeTop withInset:insets.top]]; + [constraints addObject:[self autoPinEdgeToSuperviewSafeArea:ALEdgeLeading withInset:insets.left]]; + [constraints addObject:[self autoPinEdgeToSuperviewSafeArea:ALEdgeBottom withInset:insets.bottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewSafeArea:ALEdgeTrailing withInset:insets.right]]; + return constraints; +} + +/** + Pins 3 of the 4 edges of the view to the edges of its superview anchor with the given edge insets, excluding one edge. + The insets.left corresponds to a leading edge constraint, and insets.right corresponds to a trailing edge constraint. + + @param insets The insets for this view's edges from its superview's edges. The inset corresponding to the excluded edge + will be ignored. + @param edge The edge of this view to exclude in pinning to its superview anchor; this method will not apply any constraint to it. + @return An array of constraints added, ordered counterclockwise from top. + */ +- (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewSafeAreaWithInsets:(ALEdgeInsets)insets excludingEdge:(ALEdge)edge +{ + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + + if (edge != ALEdgeTop) { + [constraints addObject:[self autoPinEdgeToSuperviewSafeArea:ALEdgeTop withInset:insets.top]]; + } + if (edge != ALEdgeLeading && edge != ALEdgeLeft) { + [constraints addObject:[self autoPinEdgeToSuperviewSafeArea:ALEdgeLeading withInset:insets.left]]; + } + if (edge != ALEdgeBottom) { + [constraints addObject:[self autoPinEdgeToSuperviewSafeArea:ALEdgeBottom withInset:insets.bottom]]; + } + if (edge != ALEdgeTrailing && edge != ALEdgeRight) { + [constraints addObject:[self autoPinEdgeToSuperviewSafeArea:ALEdgeTrailing withInset:insets.right]]; + } + return constraints; +} + +#endif /* TARGET_OS_IPHONE */ + #pragma mark Pin Edges to Superview /** @@ -186,7 +414,7 @@ - (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFlo /** Pins the edges of the view to the edges of its superview. - @return An array of constraints added. + @return An array of constraints added, ordered counterclockwise from top. */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewEdges { @@ -198,11 +426,11 @@ - (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFlo The insets.left corresponds to a leading edge constraint, and insets.right corresponds to a trailing edge constraint. @param insets The insets for this view's edges from its superview's edges. - @return An array of constraints added. + @return An array of constraints added, ordered counterclockwise from top. */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets { - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:insets.left]]; [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; @@ -217,22 +445,42 @@ - (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFlo @param insets The insets for this view's edges from its superview's edges. The inset corresponding to the excluded edge will be ignored. @param edge The edge of this view to exclude in pinning to its superview; this method will not apply any constraint to it. - @return An array of constraints added. + @return An array of constraints added, ordered counterclockwise from top. */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets excludingEdge:(ALEdge)edge { - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; - if (edge != ALEdgeTop) { - [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; - } - if (edge != ALEdgeLeading && edge != ALEdgeLeft) { - [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:insets.left]]; - } - if (edge != ALEdgeBottom) { - [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; - } - if (edge != ALEdgeTrailing && edge != ALEdgeRight) { - [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:insets.right]]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + switch (edge) { + case ALEdgeLeft: + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeRight withInset:insets.right]]; + break; + case ALEdgeRight: + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:insets.left]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; + break; + case ALEdgeTop: + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:insets.left]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:insets.right]]; + break; + case ALEdgeBottom: + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:insets.left]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:insets.right]]; + break; + case ALEdgeLeading: + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:insets.right]]; + break; + case ALEdgeTrailing: + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:insets.left]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; + break; } return constraints; } @@ -250,6 +498,26 @@ - (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge return [self autoPinEdgeToSuperviewMargin:edge relation:NSLayoutRelationEqual]; } +/** + Pins the given edge of the view to the corresponding margin of its superview with an inset. + + @param edge The edge of this view to pin to the corresponding margin of its superview. + @param inset The amount to inset this view's edge from the corresponding margin of its superview edge. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge withInset:(CGFloat)inset +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + ALView *superview = self.superview; + NSAssert(superview, @"View's superview must not be nil.\nView: %@", self); + if (edge == ALEdgeBottom || edge == ALEdgeRight || edge == ALEdgeTrailing) { + // The bottom, right, and trailing insets (and relations, if an inequality) are inverted to become offsets + inset = -inset; + } + ALMargin margin = [NSLayoutConstraint al_marginForEdge:edge]; + return [self autoConstrainAttribute:(ALAttribute)edge toAttribute:(ALAttribute)margin ofView:superview withOffset:inset]; +} + /** Pins the given edge of the view to the corresponding margin of its superview as a maximum or minimum. @@ -273,19 +541,31 @@ - (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge relation:(NSLa ALMargin margin = [NSLayoutConstraint al_marginForEdge:edge]; return [self autoConstrainAttribute:(ALAttribute)edge toAttribute:(ALAttribute)margin ofView:superview withOffset:0.0 relation:relation]; } - + /** Pins the edges of the view to the margins of its superview. - @return An array of constraints added. + @return An array of constraints added, ordered counterclockwise from top. */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewMargins { - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; - [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; - [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeading]]; - [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; - [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTrailing]]; + return [self autoPinEdgesToSuperviewMarginsWithInsets:ALEdgeInsetsZero]; +} + +/** + Pins the edges of the view to the edges of its corresponding margins of its superview with the given edge insets. + The insets.left corresponds to a leading edge constraint, and insets.right corresponds to a trailing edge constraint. + + @param insets The insets for this view's edges from its corresponding margin of its superview. + @return An array of constraints added, ordered counterclockwise from top. + */ +- (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewMarginsWithInsets:(ALEdgeInsets)insets +{ + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop withInset:insets.top]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeading withInset:insets.left]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom withInset:insets.bottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTrailing withInset:insets.right]]; return constraints; } @@ -293,22 +573,42 @@ - (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge relation:(NSLa Pins 3 of the 4 edges of the view to the margins of its superview, excluding one edge. @param edge The edge of this view to exclude in pinning to its superview; this method will not apply any constraint to it. - @return An array of constraints added. + @return An array of constraints added, ordered counterclockwise from top. */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewMarginsExcludingEdge:(ALEdge)edge { - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; - if (edge != ALEdgeTop) { - [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; - } - if (edge != ALEdgeLeading && edge != ALEdgeLeft) { - [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeading]]; - } - if (edge != ALEdgeBottom) { - [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; - } - if (edge != ALEdgeTrailing && edge != ALEdgeRight) { - [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTrailing]]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + switch (edge) { + case ALEdgeLeft: + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeRight]]; + break; + case ALEdgeRight: + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeft]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; + break; + case ALEdgeTop: + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeading]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTrailing]]; + break; + case ALEdgeBottom: + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeading]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTrailing]]; + break; + case ALEdgeLeading: + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTrailing]]; + break; + case ALEdgeTrailing: + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeading]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; + break; } return constraints; } @@ -360,7 +660,6 @@ - (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(A return [self autoConstrainAttribute:(ALAttribute)edge toAttribute:(ALAttribute)toEdge ofView:otherView withOffset:offset relation:relation]; } - #pragma mark Align Axes /** @@ -486,7 +785,7 @@ - (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(A */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoSetDimensionsToSize:(CGSize)size { - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; [constraints addObject:[self autoSetDimension:ALDimensionWidth toSize:size.width]]; [constraints addObject:[self autoSetDimension:ALDimensionHeight toSize:size.height]]; return constraints; @@ -657,7 +956,7 @@ - (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribut #pragma mark Pin to Layout Guides #if TARGET_OS_IPHONE - +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_11_0 // Top and bottom layout guides were deprecated in iOS 11 /** Pins the top edge of the view to the top layout guide of the given view controller with an inset. For compatibility with iOS 6 (where layout guides do not exist), this method will simply pin the top edge of @@ -719,9 +1018,9 @@ - (NSLayoutConstraint *)autoPinToBottomLayoutGuideOfViewController:(UIViewContro } } +#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED */ #endif /* TARGET_OS_IPHONE */ - #pragma mark Internal Methods /** diff --git a/PureLayout/PureLayout/NSArray+PureLayout.m b/PureLayout/PureLayout/NSArray+PureLayout.m index 0f8aba4..a66f05e 100755 --- a/PureLayout/PureLayout/NSArray+PureLayout.m +++ b/PureLayout/PureLayout/NSArray+PureLayout.m @@ -121,7 +121,7 @@ - (instancetype)autoIdentifyConstraints:(NSString *)identifier - (PL__NSArray_of(NSLayoutConstraint *) *)autoAlignViewsToEdge:(ALEdge)edge { NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views."); - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; ALView *previousView = nil; for (id object in self) { if ([object isKindOfClass:[ALView class]]) { @@ -146,7 +146,7 @@ - (instancetype)autoIdentifyConstraints:(NSString *)identifier - (PL__NSArray_of(NSLayoutConstraint *) *)autoAlignViewsToAxis:(ALAxis)axis { NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views."); - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; ALView *previousView = nil; for (id object in self) { if ([object isKindOfClass:[ALView class]]) { @@ -171,7 +171,7 @@ - (instancetype)autoIdentifyConstraints:(NSString *)identifier - (PL__NSArray_of(NSLayoutConstraint *) *)autoMatchViewsDimension:(ALDimension)dimension { NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views."); - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; ALView *previousView = nil; for (id object in self) { if ([object isKindOfClass:[ALView class]]) { @@ -197,7 +197,7 @@ - (instancetype)autoIdentifyConstraints:(NSString *)identifier - (PL__NSArray_of(NSLayoutConstraint *) *)autoSetViewsDimension:(ALDimension)dimension toSize:(CGFloat)size { NSAssert([self al_containsMinimumNumberOfViews:1], @"This array must contain at least 1 view."); - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; for (id object in self) { if ([object isKindOfClass:[ALView class]]) { ALView *view = (ALView *)object; @@ -217,7 +217,7 @@ - (instancetype)autoIdentifyConstraints:(NSString *)identifier */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoSetViewsDimensionsToSize:(CGSize)size { - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; [constraints addObjectsFromArray:[self autoSetViewsDimension:ALDimensionWidth toSize:size.width]]; [constraints addObjectsFromArray:[self autoSetViewsDimension:ALDimensionHeight toSize:size.height]]; return constraints; @@ -311,7 +311,7 @@ Views will be the same size (variable) in the dimension along the axis and will CGFloat leadingSpacing = shouldSpaceInsets ? spacing : 0.0; CGFloat trailingSpacing = shouldSpaceInsets ? spacing : 0.0; - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; ALView *previousView = nil; for (id object in self) { if ([object isKindOfClass:[ALView class]]) { @@ -396,18 +396,20 @@ Views will be the same size (fixed) in the dimension along the axis and will hav return nil; } #if TARGET_OS_IPHONE -# if !defined(PURELAYOUT_APP_EXTENSIONS) - BOOL isRightToLeftLayout = [[UIApplication sharedApplication] userInterfaceLayoutDirection] == UIUserInterfaceLayoutDirectionRightToLeft; -# else - // App Extensions may not access -[UIApplication sharedApplication]; fall back to checking the bundle's preferred localization character direction - BOOL isRightToLeftLayout = [NSLocale characterDirectionForLanguage:[[NSBundle mainBundle] preferredLocalizations][0]] == NSLocaleLanguageDirectionRightToLeft; -# endif /* !defined(PURELAYOUT_APP_EXTENSIONS) */ + BOOL isRightToLeftLayout; + if ([[[[NSBundle mainBundle] bundlePath] pathExtension] isEqualToString:@"appex"]) { + // App Extensions may not access -[UIApplication sharedApplication]; fall back to checking the bundle's preferred localization character direction + isRightToLeftLayout = [NSLocale characterDirectionForLanguage:[[NSBundle mainBundle] preferredLocalizations][0]] == NSLocaleLanguageDirectionRightToLeft; + } else { + // Use dynamic call to sharedApplication to workaround compilation error when building against app extensions + isRightToLeftLayout = [[UIApplication performSelector:@selector(sharedApplication)] userInterfaceLayoutDirection] == UIUserInterfaceLayoutDirectionRightToLeft; + } #else BOOL isRightToLeftLayout = [[NSApplication sharedApplication] userInterfaceLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft; #endif /* TARGET_OS_IPHONE */ BOOL shouldFlipOrder = isRightToLeftLayout && (axis != ALAxisVertical); // imitate the effect of leading/trailing when distributing horizontally - __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + PL__NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; PL__NSArray_of(ALView *) *views = [self al_copyViewsOnly]; NSUInteger numberOfViews = [views count]; ALView *commonSuperview = [views al_commonSuperviewOfViews]; @@ -493,7 +495,7 @@ - (BOOL)al_containsMinimumNumberOfViews:(NSUInteger)minimumNumberOfViews */ - (PL__NSArray_of(ALView *) *)al_copyViewsOnly { - __NSMutableArray_of(ALView *) *viewsOnlyArray = [NSMutableArray arrayWithCapacity:[self count]]; + PL__NSMutableArray_of(ALView *) *viewsOnlyArray = [NSMutableArray arrayWithCapacity:[self count]]; for (id object in self) { if ([object isKindOfClass:[ALView class]]) { [viewsOnlyArray addObject:object]; diff --git a/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m b/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m index 49a8349..4ee751d 100755 --- a/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m +++ b/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m @@ -46,7 +46,7 @@ @implementation NSLayoutConstraint (PureLayout) NOTE: Access to this variable is not synchronized (and should only be done on the main thread). */ -static __NSMutableArray_of(__NSMutableArray_of(NSLayoutConstraint *) *) *_al_arraysOfCreatedConstraints = nil; +static PL__NSMutableArray_of(PL__NSMutableArray_of(NSLayoutConstraint *) *) *_al_arraysOfCreatedConstraints = nil; /** A global variable that is set to YES when installing a batch of constraints collected from a call to +[autoCreateAndInstallConstraints]. @@ -59,7 +59,7 @@ should not return constraints from within the blocks of nested call(s). /** Accessor for the global state that stores arrays of constraints created without being installed. */ -+ (__NSMutableArray_of(__NSMutableArray_of(NSLayoutConstraint *) *) *)al_arraysOfCreatedConstraints ++ (PL__NSMutableArray_of(PL__NSMutableArray_of(NSLayoutConstraint *) *) *)al_arraysOfCreatedConstraints { NSAssert([NSThread isMainThread], @"PureLayout is not thread safe, and must be used exclusively from the main thread."); if (!_al_arraysOfCreatedConstraints) { @@ -71,7 +71,7 @@ should not return constraints from within the blocks of nested call(s). /** Accessor for the current mutable array of constraints created without being immediately installed. */ -+ (__NSMutableArray_of(NSLayoutConstraint *) *)al_currentArrayOfCreatedConstraints ++ (PL__NSMutableArray_of(NSLayoutConstraint *) *)al_currentArrayOfCreatedConstraints { return [[self al_arraysOfCreatedConstraints] lastObject]; } @@ -95,7 +95,7 @@ This may be more efficient than installing (activating) each constraint one-by-o @param block A block of method calls to the PureLayout API that create constraints. @return An array of the constraints that were created from calls to the PureLayout API inside the block. */ -+ (PL__NSArray_of(NSLayoutConstraint *) *)autoCreateAndInstallConstraints:(ALConstraintsBlock)block ++ (PL__NSArray_of(NSLayoutConstraint *) *)autoCreateAndInstallConstraints:(__attribute__((noescape)) ALConstraintsBlock)block { NSArray *createdConstraints = [self autoCreateConstraintsWithoutInstalling:block]; _al_isInstallingCreatedConstraints = YES; @@ -114,7 +114,7 @@ Creates all of the constraints in the block but prevents them from being automat @param block A block of method calls to the PureLayout API that create constraints. @return An array of the constraints that were created from calls to the PureLayout API inside the block. */ -+ (PL__NSArray_of(NSLayoutConstraint *) *)autoCreateConstraintsWithoutInstalling:(ALConstraintsBlock)block ++ (PL__NSArray_of(NSLayoutConstraint *) *)autoCreateConstraintsWithoutInstalling:(__attribute__((noescape)) ALConstraintsBlock)block { NSAssert(block, @"The constraints block cannot be nil."); NSArray *createdConstraints = nil; @@ -138,12 +138,12 @@ Creates all of the constraints in the block but prevents them from being automat constraints created by this library (even if automatic constraint installation is being prevented). NOTE: Access to this variable is not synchronized (and should only be done on the main thread). */ -static __NSMutableArray_of(NSNumber *) *_al_globalConstraintPriorities = nil; +static PL__NSMutableArray_of(NSNumber *) *_al_globalConstraintPriorities = nil; /** Accessor for the global stack of layout priorities. */ -+ (__NSMutableArray_of(NSNumber *) *)al_globalConstraintPriorities ++ (PL__NSMutableArray_of(NSNumber *) *)al_globalConstraintPriorities { NSAssert([NSThread isMainThread], @"PureLayout is not thread safe, and must be used exclusively from the main thread."); if (!_al_globalConstraintPriorities) { @@ -159,7 +159,7 @@ constraints created by this library (even if automatic constraint installation i */ + (ALLayoutPriority)al_currentGlobalConstraintPriority { - __NSMutableArray_of(NSNumber *) *globalConstraintPriorities = [self al_globalConstraintPriorities]; + PL__NSMutableArray_of(NSNumber *) *globalConstraintPriorities = [self al_globalConstraintPriorities]; if ([globalConstraintPriorities count] == 0) { return ALLayoutPriorityRequired; } @@ -184,7 +184,7 @@ + (BOOL)al_isExecutingPriorityConstraintsBlock @param priority The layout priority to be set on all constraints created in the constraints block. @param block A block of method calls to the PureLayout API that create and install constraints. */ -+ (void)autoSetPriority:(ALLayoutPriority)priority forConstraints:(ALConstraintsBlock)block ++ (void)autoSetPriority:(ALLayoutPriority)priority forConstraints:(__attribute__((noescape)) ALConstraintsBlock)block { NSAssert(block, @"The constraints block cannot be nil."); if (block) { @@ -207,12 +207,12 @@ + (void)autoSetPriority:(ALLayoutPriority)priority forConstraints:(ALConstraints constraints created by this library (even if automatic constraint installation is being prevented). NOTE: Access to this variable is not synchronized (and should only be done on the main thread). */ -static __NSMutableArray_of(NSString *) *_al_globalConstraintIdentifiers = nil; +static PL__NSMutableArray_of(NSString *) *_al_globalConstraintIdentifiers = nil; /** Accessor for the global state of constraint identifiers. */ -+ (__NSMutableArray_of(NSString *) *)al_globalConstraintIdentifiers ++ (PL__NSMutableArray_of(NSString *) *)al_globalConstraintIdentifiers { NSAssert([NSThread isMainThread], @"PureLayout is not thread safe, and must be used exclusively from the main thread."); if (!_al_globalConstraintIdentifiers) { @@ -228,7 +228,7 @@ constraints created by this library (even if automatic constraint installation i */ + (NSString *)al_currentGlobalConstraintIdentifier { - __NSMutableArray_of(NSString *) *globalConstraintIdentifiers = [self al_globalConstraintIdentifiers]; + PL__NSMutableArray_of(NSString *) *globalConstraintIdentifiers = [self al_globalConstraintIdentifiers]; if ([globalConstraintIdentifiers count] == 0) { return nil; } @@ -244,7 +244,7 @@ + (NSString *)al_currentGlobalConstraintIdentifier @param identifier A string used to identify all constraints created in the constraints block. @param block A block of method calls to the PureLayout API that create and install constraints. */ -+ (void)autoSetIdentifier:(NSString *)identifier forConstraints:(ALConstraintsBlock)block ++ (void)autoSetIdentifier:(NSString *)identifier forConstraints:(__attribute__((noescape)) ALConstraintsBlock)block { NSAssert(block, @"The constraints block cannot be nil."); NSAssert(identifier, @"The identifier string cannot be nil."); @@ -373,73 +373,73 @@ + (NSLayoutAttribute)al_layoutAttributeForAttribute:(ALAttribute)attribute { NSLayoutAttribute layoutAttribute = NSLayoutAttributeNotAnAttribute; switch (attribute) { - case ALEdgeLeft: + case ALAttributeLeft: layoutAttribute = NSLayoutAttributeLeft; break; - case ALEdgeRight: + case ALAttributeRight: layoutAttribute = NSLayoutAttributeRight; break; - case ALEdgeTop: + case ALAttributeTop: layoutAttribute = NSLayoutAttributeTop; break; - case ALEdgeBottom: + case ALAttributeBottom: layoutAttribute = NSLayoutAttributeBottom; break; - case ALEdgeLeading: + case ALAttributeLeading: layoutAttribute = NSLayoutAttributeLeading; break; - case ALEdgeTrailing: + case ALAttributeTrailing: layoutAttribute = NSLayoutAttributeTrailing; break; - case ALDimensionWidth: + case ALAttributeWidth: layoutAttribute = NSLayoutAttributeWidth; break; - case ALDimensionHeight: + case ALAttributeHeight: layoutAttribute = NSLayoutAttributeHeight; break; - case ALAxisVertical: + case ALAttributeVertical: layoutAttribute = NSLayoutAttributeCenterX; break; - case ALAxisHorizontal: + case ALAttributeHorizontal: layoutAttribute = NSLayoutAttributeCenterY; break; - case ALAxisBaseline: // same value as ALAxisLastBaseline + case ALAttributeBaseline: // same value as ALAxisLastBaseline layoutAttribute = NSLayoutAttributeBaseline; break; #if PL__PureLayout_MinBaseSDK_iOS_8_0 - case ALAxisFirstBaseline: + case ALAttributeFirstBaseline: NSAssert(PL__PureLayout_MinSysVer_iOS_8_0, @"ALAxisFirstBaseline is only supported on iOS 8.0 or higher."); layoutAttribute = NSLayoutAttributeFirstBaseline; break; - case ALMarginLeft: + case ALAttributeMarginLeft: NSAssert(PL__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeLeftMargin is only supported on iOS 8.0 or higher."); layoutAttribute = NSLayoutAttributeLeftMargin; break; - case ALMarginRight: + case ALAttributeMarginRight: NSAssert(PL__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeRightMargin is only supported on iOS 8.0 or higher."); layoutAttribute = NSLayoutAttributeRightMargin; break; - case ALMarginTop: + case ALAttributeMarginTop: NSAssert(PL__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeTopMargin is only supported on iOS 8.0 or higher."); layoutAttribute = NSLayoutAttributeTopMargin; break; - case ALMarginBottom: + case ALAttributeMarginBottom: NSAssert(PL__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeBottomMargin is only supported on iOS 8.0 or higher."); layoutAttribute = NSLayoutAttributeBottomMargin; break; - case ALMarginLeading: + case ALAttributeMarginLeading: NSAssert(PL__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeLeadingMargin is only supported on iOS 8.0 or higher."); layoutAttribute = NSLayoutAttributeLeadingMargin; break; - case ALMarginTrailing: + case ALAttributeMarginTrailing: NSAssert(PL__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeTrailingMargin is only supported on iOS 8.0 or higher."); layoutAttribute = NSLayoutAttributeTrailingMargin; break; - case ALMarginAxisVertical: + case ALAttributeMarginAxisVertical: NSAssert(PL__PureLayout_MinSysVer_iOS_8_0, @"ALAxisVerticalMargin is only supported on iOS 8.0 or higher."); layoutAttribute = NSLayoutAttributeCenterXWithinMargins; break; - case ALMarginAxisHorizontal: + case ALAttributeMarginAxisHorizontal: NSAssert(PL__PureLayout_MinSysVer_iOS_8_0, @"ALAxisHorizontalMargin is only supported on iOS 8.0 or higher."); layoutAttribute = NSLayoutAttributeCenterYWithinMargins; break; diff --git a/PureLayout/PureLayout/PureLayout+Internal.h b/PureLayout/PureLayout/PureLayout+Internal.h index 2a2c5eb..15c2eeb 100644 --- a/PureLayout/PureLayout/PureLayout+Internal.h +++ b/PureLayout/PureLayout/PureLayout+Internal.h @@ -29,7 +29,7 @@ // Using generics with NSMutableArray is so common in the internal implementation of PureLayout that it gets a dedicated preprocessor macro for better readability. -#define __NSMutableArray_of(type) PL__GENERICS(NSMutableArray, type) +#define PL__NSMutableArray_of(type) PL__GENERICS(NSMutableArray, type) PL__ASSUME_NONNULL_BEGIN @@ -68,11 +68,11 @@ static const CGFloat kMULTIPLIER_MIN_VALUE = (CGFloat)0.00001; // very small flo @interface NSLayoutConstraint (PureLayoutInternal) + (BOOL)al_preventAutomaticConstraintInstallation; -+ (__NSMutableArray_of(NSLayoutConstraint *) *)al_currentArrayOfCreatedConstraints; ++ (PL__NSMutableArray_of(NSLayoutConstraint *) *)al_currentArrayOfCreatedConstraints; + (BOOL)al_isExecutingPriorityConstraintsBlock; + (ALLayoutPriority)al_currentGlobalConstraintPriority; #if PL__PureLayout_MinBaseSDK_iOS_8_0 || PL__PureLayout_MinBaseSDK_OSX_10_10 -+ (NSString *)al_currentGlobalConstraintIdentifier; ++ (nullable NSString *)al_currentGlobalConstraintIdentifier; #endif /* PL__PureLayout_MinBaseSDK_iOS_8_0 || PL__PureLayout_MinBaseSDK_OSX_10_10 */ + (void)al_applyGlobalStateToConstraint:(NSLayoutConstraint *)constraint; + (NSLayoutAttribute)al_layoutAttributeForAttribute:(ALAttribute)attribute; diff --git a/PureLayout/PureLayout/ALView+PureLayout.h b/PureLayout/PureLayout/include/ALView+PureLayout.h similarity index 84% rename from PureLayout/PureLayout/ALView+PureLayout.h rename to PureLayout/PureLayout/include/ALView+PureLayout.h index 6e61014..ced5859 100755 --- a/PureLayout/PureLayout/ALView+PureLayout.h +++ b/PureLayout/PureLayout/include/ALView+PureLayout.h @@ -69,6 +69,29 @@ PL__ASSUME_NONNULL_BEGIN #endif /* PL__PureLayout_MinBaseSDK_iOS_8_0 */ +#if TARGET_OS_IPHONE + +#pragma mark Pin Edges to SafeArea + +/** Pins the given edge of the view to the same edge of its superview anchor/edge. */ +- (NSLayoutConstraint *)API_AVAILABLE(ios(9.0), tvos(9.0))autoPinEdgeToSuperviewSafeArea:(ALEdge)edge; + +/** Pins the given edge of the view to the same edge of its superview anchor/edge with an inset. */ +- (NSLayoutConstraint *)API_AVAILABLE(ios(9.0), tvos(9.0))autoPinEdgeToSuperviewSafeArea:(ALEdge)edge withInset:(CGFloat)inset; + +/** Pins the given edge of the view to the same edge of its superview anchor/edge with an inset as a maximum or minimum. */ +- (NSLayoutConstraint *)API_AVAILABLE(ios(9.0), tvos(9.0))autoPinEdgeToSuperviewSafeArea:(ALEdge)edge withInset:(CGFloat)inset relation:(NSLayoutRelation)relation; + +/** Pins the edges of the view to the edges of its superview anchors/edge. */ +- (PL__NSArray_of(NSLayoutConstraint *) *)API_AVAILABLE(ios(9.0), tvos(9.0))autoPinEdgesToSuperviewSafeArea; + +/** Pins the edges of the view to the edges of its superview anchors/edges with the given edge insets. */ +- (PL__NSArray_of(NSLayoutConstraint *) *)API_AVAILABLE(ios(9.0), tvos(9.0))autoPinEdgesToSuperviewSafeAreaWithInsets:(ALEdgeInsets)insets; + +/** Pins 3 of the 4 edges of the view to the edges of its superview anchor/edge with the given edge insets, excluding one edge. */ +- (PL__NSArray_of(NSLayoutConstraint *) *)API_AVAILABLE(ios(9.0), tvos(9.0))autoPinEdgesToSuperviewSafeAreaWithInsets:(ALEdgeInsets)insets excludingEdge:(ALEdge)edge; + +#endif /* TARGET_OS_IPHONE */ #pragma mark Pin Edges to Superview @@ -95,12 +118,18 @@ PL__ASSUME_NONNULL_BEGIN /** Pins the given edge of the view to the corresponding margin of its superview. Available in iOS 8.0 and later. */ - (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge; +/** Pins the given edge of a view to the corresponding margin of its superview with an inset.*/ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge withInset:(CGFloat)inset; + /** Pins the given edge of the view to the corresponding margin of its superview as a maximum or minimum. Available in iOS 8.0 and later. */ - (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge relation:(NSLayoutRelation)relation; /** Pins the edges of the view to the margins of its superview. Available in iOS 8.0 and later. */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewMargins; +/** Pins the edges of the view to the margins of its superview with the given edge insets. Available in iOS 8.0 and later.*/ +- (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewMarginsWithInsets:(ALEdgeInsets)insets; + /** Pins 3 of the 4 edges of the view to the margins of its superview excluding one edge. Available in iOS 8.0 and later. */ - (PL__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewMarginsExcludingEdge:(ALEdge)edge; @@ -193,6 +222,7 @@ PL__ASSUME_NONNULL_BEGIN #pragma mark Pin to Layout Guides (iOS only) #if TARGET_OS_IPHONE +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_11_0 // Top and bottom layout guides were deprecated in iOS 11 /** Pins the top edge of the view to the top layout guide of the given view controller with an inset. Available on iOS only. */ - (NSLayoutConstraint *)autoPinToTopLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset; @@ -206,6 +236,7 @@ PL__ASSUME_NONNULL_BEGIN /** Pins the bottom edge of the view to the bottom layout guide of the given view controller with an inset as a maximum or minimum. Available on iOS only. */ - (NSLayoutConstraint *)autoPinToBottomLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset relation:(NSLayoutRelation)relation; +#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED */ #endif /* TARGET_OS_IPHONE */ @end diff --git a/PureLayout/PureLayout/NSArray+PureLayout.h b/PureLayout/PureLayout/include/NSArray+PureLayout.h similarity index 100% rename from PureLayout/PureLayout/NSArray+PureLayout.h rename to PureLayout/PureLayout/include/NSArray+PureLayout.h diff --git a/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h b/PureLayout/PureLayout/include/NSLayoutConstraint+PureLayout.h similarity index 93% rename from PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h rename to PureLayout/PureLayout/include/NSLayoutConstraint+PureLayout.h index 272875c..ae48ca0 100755 --- a/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h +++ b/PureLayout/PureLayout/include/NSLayoutConstraint+PureLayout.h @@ -43,18 +43,18 @@ PL__ASSUME_NONNULL_BEGIN /** Creates all of the constraints in the block, then installs (activates) them all at once. All constraints created from calls to the PureLayout API in the block are returned in a single array. This may be more efficient than installing (activating) each constraint one-by-one. */ -+ (PL__NSArray_of(NSLayoutConstraint *) *)autoCreateAndInstallConstraints:(ALConstraintsBlock)block; ++ (PL__NSArray_of(NSLayoutConstraint *) *)autoCreateAndInstallConstraints:(__attribute__((noescape)) ALConstraintsBlock)block; /** Creates all of the constraints in the block but prevents them from being automatically installed (activated). All constraints created from calls to the PureLayout API in the block are returned in a single array. */ -+ (PL__NSArray_of(NSLayoutConstraint *) *)autoCreateConstraintsWithoutInstalling:(ALConstraintsBlock)block; ++ (PL__NSArray_of(NSLayoutConstraint *) *)autoCreateConstraintsWithoutInstalling:(__attribute__((noescape)) ALConstraintsBlock)block; #pragma mark Set Priority For Constraints /** Sets the constraint priority to the given value for all constraints created using the PureLayout API within the given constraints block. NOTE: This method will have no effect (and will NOT set the priority) on constraints created or added without using the PureLayout API! */ -+ (void)autoSetPriority:(ALLayoutPriority)priority forConstraints:(ALConstraintsBlock)block; ++ (void)autoSetPriority:(ALLayoutPriority)priority forConstraints:(__attribute__((noescape)) ALConstraintsBlock)block; #pragma mark Identify Constraints @@ -63,7 +63,7 @@ PL__ASSUME_NONNULL_BEGIN /** Sets the identifier for all constraints created using the PureLayout API within the given constraints block. NOTE: This method will have no effect (and will NOT set the identifier) on constraints created or added without using the PureLayout API! */ -+ (void)autoSetIdentifier:(NSString *)identifier forConstraints:(ALConstraintsBlock)block; ++ (void)autoSetIdentifier:(NSString *)identifier forConstraints:(__attribute__((noescape)) ALConstraintsBlock)block; /** Sets the string as the identifier for this constraint. Available in iOS 7.0 and OS X 10.9 and later. */ - (instancetype)autoIdentify:(NSString *)identifier; diff --git a/PureLayout/PureLayout/PureLayout.h b/PureLayout/PureLayout/include/PureLayout.h similarity index 100% rename from PureLayout/PureLayout/PureLayout.h rename to PureLayout/PureLayout/include/PureLayout.h diff --git a/PureLayout/PureLayout/PureLayoutDefines.h b/PureLayout/PureLayout/include/PureLayoutDefines.h similarity index 93% rename from PureLayout/PureLayout/PureLayoutDefines.h rename to PureLayout/PureLayout/include/PureLayoutDefines.h index 2e88ace..56bd197 100755 --- a/PureLayout/PureLayout/PureLayoutDefines.h +++ b/PureLayout/PureLayout/include/PureLayoutDefines.h @@ -29,14 +29,18 @@ #define PureLayoutDefines_h #import - +// check the code in - // Define some preprocessor macros to check for a minimum Base SDK. These are used to prevent compile-time errors in older versions of Xcode. #define PL__PureLayout_MinBaseSDK_iOS_8_0 (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1) +#define PL__PureLayout_MinBaseSDK_iOS_9_0 (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_8_4) +#define PL__PureLayout_MinBaseSDK_iOS_11_0 (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_10_3) #define PL__PureLayout_MinBaseSDK_OSX_10_10 (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9) // Define some preprocessor macros to check for a minimum System Version. These are used to prevent runtime crashes on older versions of iOS/OS X. #define PL__PureLayout_MinSysVer_iOS_7_0 (TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) #define PL__PureLayout_MinSysVer_iOS_8_0 (TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) +#define PL__PureLayout_MinSysVer_iOS_9_0 (TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_8_x_Max) +#define PL__PureLayout_MinSysVer_iOS_10_0 (TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) #define PL__PureLayout_MinSysVer_OSX_10_9 (!TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8_4) // Define some preprocessor macros that allow nullability annotations to be adopted in a backwards-compatible manner. @@ -101,7 +105,7 @@ #pragma mark PureLayout Attributes /** Constants that represent edges of a view. */ -typedef NS_ENUM(NSInteger, ALEdge) { +typedef NS_CLOSED_ENUM(NSInteger, ALEdge) { /** The left edge of the view. */ ALEdgeLeft = NSLayoutAttributeLeft, /** The right edge of the view. */ @@ -117,7 +121,7 @@ typedef NS_ENUM(NSInteger, ALEdge) { }; /** Constants that represent dimensions of a view. */ -typedef NS_ENUM(NSInteger, ALDimension) { +typedef NS_CLOSED_ENUM(NSInteger, ALDimension) { /** The width of the view. */ ALDimensionWidth = NSLayoutAttributeWidth, /** The height of the view. */ @@ -125,7 +129,7 @@ typedef NS_ENUM(NSInteger, ALDimension) { }; /** Constants that represent axes of a view. */ -typedef NS_ENUM(NSInteger, ALAxis) { +typedef NS_CLOSED_ENUM(NSInteger, ALAxis) { /** A vertical line equidistant from the view's left and right edges. */ ALAxisVertical = NSLayoutAttributeCenterX, /** A horizontal line equidistant from the view's top and bottom edges. */ @@ -144,7 +148,7 @@ typedef NS_ENUM(NSInteger, ALAxis) { #if PL__PureLayout_MinBaseSDK_iOS_8_0 /** Constants that represent layout margins of a view. Available in iOS 8.0 and later. */ -typedef NS_ENUM(NSInteger, ALMargin) { +typedef NS_CLOSED_ENUM(NSInteger, ALMargin) { /** The left margin of the view, based on the view's layoutMargins left inset. */ ALMarginLeft = NSLayoutAttributeLeftMargin, /** The right margin of the view, based on the view's layoutMargins right inset. */ @@ -160,7 +164,7 @@ typedef NS_ENUM(NSInteger, ALMargin) { }; /** Constants that represent axes of the layout margins of a view. Available in iOS 8.0 and later. */ -typedef NS_ENUM(NSInteger, ALMarginAxis) { +typedef NS_CLOSED_ENUM(NSInteger, ALMarginAxis) { /** A vertical line equidistant from the view's left and right margins. */ ALMarginAxisVertical = NSLayoutAttributeCenterXWithinMargins, /** A horizontal line equidistant from the view's top and bottom margins. */ @@ -171,7 +175,7 @@ typedef NS_ENUM(NSInteger, ALMarginAxis) { /** An attribute of a view that can be used in auto layout constraints. These constants are identical to the more specific enum types: ALEdge, ALAxis, ALDimension, ALMargin, ALMarginAxis. It is safe to cast a more specific enum type to the ALAttribute type. */ -typedef NS_ENUM(NSInteger, ALAttribute) { +typedef NS_CLOSED_ENUM(NSInteger, ALAttribute) { /** The left edge of the view. */ ALAttributeLeft = ALEdgeLeft, /** The right edge of the view. */ diff --git a/PureLayout/PureLayoutTests/PureLayoutBatchTests.m b/PureLayout/PureLayoutTests/PureLayoutBatchTests.m index 09ae16e..8f8b37b 100644 --- a/PureLayout/PureLayoutTests/PureLayoutBatchTests.m +++ b/PureLayout/PureLayoutTests/PureLayoutBatchTests.m @@ -14,18 +14,6 @@ @interface PureLayoutBatchTests : PureLayoutTestBase @implementation PureLayoutBatchTests -- (void)setUp -{ - [super setUp]; - -} - -- (void)tearDown -{ - - [super tearDown]; -} - /** Returns YES if the constraint is active. */ - (BOOL)isConstraintActive:(NSLayoutConstraint *)constraint { @@ -78,7 +66,7 @@ - (BOOL)noConstraintsAreActivated:(PL__NSArray_of(NSLayoutConstraint *) *)constr */ - (void)testCreateAndInstallConstraints { - __NSMutableArray_of(NSLayoutConstraint *) *createdConstraints = [NSMutableArray array]; + PL__NSMutableArray_of(NSLayoutConstraint *) *createdConstraints = [NSMutableArray array]; PL__NSArray_of(NSLayoutConstraint *) *returnedConstraints = [NSLayoutConstraint autoCreateAndInstallConstraints:^{ [createdConstraints addObjectsFromArray:[self.viewA autoPinEdgesToSuperviewEdges]]; [createdConstraints addObject:[self.viewA_A autoAlignAxis:ALAxisHorizontal toSameAxisOfView:self.viewA_A.superview]]; @@ -149,7 +137,7 @@ - (void)testCreateAndInstallConstraintsNested */ - (void)testCreateConstraintsWithoutInstalling { - __NSMutableArray_of(NSLayoutConstraint *) *createdConstraints = [NSMutableArray array]; + PL__NSMutableArray_of(NSLayoutConstraint *) *createdConstraints = [NSMutableArray array]; PL__NSArray_of(NSLayoutConstraint *) *returnedConstraints = [NSLayoutConstraint autoCreateConstraintsWithoutInstalling:^{ [createdConstraints addObjectsFromArray:[self.viewA autoPinEdgesToSuperviewEdgesWithInsets:ALEdgeInsetsMake(10.0, 10.0, 10.0, 10.0) excludingEdge:ALEdgeBottom]]; [createdConstraints addObject:[self.viewA_A autoAlignAxis:ALAxisVertical toSameAxisOfView:self.viewA_A.superview]]; diff --git a/PureLayout/PureLayoutTests/PureLayoutCenteringTests.m b/PureLayout/PureLayoutTests/PureLayoutCenteringTests.m index 63e997d..c1ec19f 100644 --- a/PureLayout/PureLayoutTests/PureLayoutCenteringTests.m +++ b/PureLayout/PureLayoutTests/PureLayoutCenteringTests.m @@ -14,18 +14,6 @@ @interface PureLayoutCenteringTests : PureLayoutTestBase @implementation PureLayoutCenteringTests -- (void)setUp -{ - [super setUp]; - -} - -- (void)tearDown -{ - - [super tearDown]; -} - - (void)testAutoCenterInSuperview { [self.viewA autoSetDimensionsToSize:CGSizeMake(100.0, 100.0)]; diff --git a/PureLayout/PureLayoutTests/PureLayoutDistributeTests.m b/PureLayout/PureLayoutTests/PureLayoutDistributeTests.m index ababd93..8b95551 100644 --- a/PureLayout/PureLayoutTests/PureLayoutDistributeTests.m +++ b/PureLayout/PureLayoutTests/PureLayoutDistributeTests.m @@ -17,16 +17,6 @@ @interface PureLayoutDistributeTests : PureLayoutTestBase @implementation PureLayoutDistributeTests -- (void)setUp -{ - [super setUp]; -} - -- (void)tearDown -{ - [super tearDown]; -} - - (void)testAutoDistributeViewsHorizontallyWithFixedSpacing { PL__NSArray_of(NSLayoutConstraint *) *constraints = nil; diff --git a/PureLayout/PureLayoutTests/PureLayoutIdentifierTests.m b/PureLayout/PureLayoutTests/PureLayoutIdentifierTests.m index 2d5f51e..e8c5464 100644 --- a/PureLayout/PureLayoutTests/PureLayoutIdentifierTests.m +++ b/PureLayout/PureLayoutTests/PureLayoutIdentifierTests.m @@ -14,18 +14,6 @@ @interface PureLayoutIdentifierTests : PureLayoutTestBase @implementation PureLayoutIdentifierTests -- (void)setUp -{ - [super setUp]; - -} - -- (void)tearDown -{ - - [super tearDown]; -} - /** Test the -[autoIdentify:] method on NSLayoutConstraint. */ - (void)testIdentify { diff --git a/PureLayout/PureLayoutTests/PureLayoutInstallationTests.m b/PureLayout/PureLayoutTests/PureLayoutInstallationTests.m index d19b1b0..e2841fa 100644 --- a/PureLayout/PureLayoutTests/PureLayoutInstallationTests.m +++ b/PureLayout/PureLayoutTests/PureLayoutInstallationTests.m @@ -14,18 +14,6 @@ @interface PureLayoutInstallationTests : PureLayoutTestBase @implementation PureLayoutInstallationTests -- (void)setUp -{ - [super setUp]; - -} - -- (void)tearDown -{ - - [super tearDown]; -} - /** Test the -[autoInstall] method on NSLayoutConstraint with two nil items. */ diff --git a/PureLayout/PureLayoutTests/PureLayoutInstantiationTests.m b/PureLayout/PureLayoutTests/PureLayoutInstantiationTests.m index 4a17df0..9cea9ca 100644 --- a/PureLayout/PureLayoutTests/PureLayoutInstantiationTests.m +++ b/PureLayout/PureLayoutTests/PureLayoutInstantiationTests.m @@ -14,18 +14,6 @@ @interface PureLayoutInstantiationTests : PureLayoutTestBase @implementation PureLayoutInstantiationTests -- (void)setUp -{ - [super setUp]; - -} - -- (void)tearDown -{ - - [super tearDown]; -} - /** Test the +[newAutoLayoutView] method. */ diff --git a/PureLayout/PureLayoutTests/PureLayoutInternalTests.m b/PureLayout/PureLayoutTests/PureLayoutInternalTests.m index 7ab2200..c6dc996 100644 --- a/PureLayout/PureLayoutTests/PureLayoutInternalTests.m +++ b/PureLayout/PureLayoutTests/PureLayoutInternalTests.m @@ -14,18 +14,6 @@ @interface PureLayoutInternalTests : PureLayoutTestBase @implementation PureLayoutInternalTests -- (void)setUp -{ - [super setUp]; - -} - -- (void)tearDown -{ - - [super tearDown]; -} - /** Test that ALAttributes translate directly to the specific enum types. */ diff --git a/PureLayout/PureLayoutTests/PureLayoutPinEdgesTests.m b/PureLayout/PureLayoutTests/PureLayoutPinEdgesTests.m index 8767171..d11f38d 100644 --- a/PureLayout/PureLayoutTests/PureLayoutPinEdgesTests.m +++ b/PureLayout/PureLayoutTests/PureLayoutPinEdgesTests.m @@ -14,18 +14,6 @@ @interface PureLayoutPinEdgesTests : PureLayoutTestBase @implementation PureLayoutPinEdgesTests -- (void)setUp -{ - [super setUp]; - -} - -- (void)tearDown -{ - - [super tearDown]; -} - - (void)testAutoPinEdgeToSuperviewEdge { [self.viewA autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:10.0]; @@ -52,4 +40,106 @@ - (void)testAutoPinEdgeToSuperviewEdge ALAssertFrameEquals(self.viewB, 500.0, VALUES(0.0, -52.0), kContainerViewWidth - 500.0, kContainerViewHeight + 52.0); } +-(void)testAutoPinEdgesReturnsConstraintsCounterclockwiseFromTop +{ + PL__NSArray_of(NSLayoutConstraint *) *constraints = [self.viewA autoPinEdgesToSuperviewEdges]; + + XCTAssertEqual([[constraints objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[constraints objectAtIndex:1] firstAttribute], NSLayoutAttributeLeading); + XCTAssertEqual([[constraints objectAtIndex:2] firstAttribute], NSLayoutAttributeBottom); + XCTAssertEqual([[constraints objectAtIndex:3] firstAttribute], NSLayoutAttributeTrailing); +} + +-(void)testAutoPinEdgesExcludingEdgeRetainsRelativeConstraintOrdering +{ + PL__NSArray_of(NSLayoutConstraint *) *constraints = [self.viewA autoPinEdgesToSuperviewEdgesWithInsets:ALEdgeInsetsZero excludingEdge:ALEdgeLeading]; + + XCTAssertEqual([[constraints objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[constraints objectAtIndex:1] firstAttribute], NSLayoutAttributeBottom); + XCTAssertEqual([[constraints objectAtIndex:2] firstAttribute], NSLayoutAttributeTrailing); +} + +-(void)testAutoPinEdgesExcludingLeftEdgeDoesNotUseTrailing +{ + PL__NSArray_of(NSLayoutConstraint *) *excludingLeft = [self.viewA autoPinEdgesToSuperviewEdgesWithInsets:ALEdgeInsetsZero excludingEdge:ALEdgeLeft]; + + XCTAssertEqual([[excludingLeft objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[excludingLeft objectAtIndex:1] firstAttribute], NSLayoutAttributeBottom); + XCTAssertEqual([[excludingLeft objectAtIndex:2] firstAttribute], NSLayoutAttributeRight); + + PL__NSArray_of(NSLayoutConstraint *) *excludingLeading = [self.viewA autoPinEdgesToSuperviewEdgesWithInsets:ALEdgeInsetsZero excludingEdge:ALEdgeLeading]; + + XCTAssertEqual([[excludingLeading objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[excludingLeading objectAtIndex:1] firstAttribute], NSLayoutAttributeBottom); + XCTAssertEqual([[excludingLeading objectAtIndex:2] firstAttribute], NSLayoutAttributeTrailing); +} + +-(void)testAutoPinEdgesExcludingRightEdgeDoesNotUseLeading +{ + PL__NSArray_of(NSLayoutConstraint *) *excludingRight = [self.viewA autoPinEdgesToSuperviewEdgesWithInsets:ALEdgeInsetsZero excludingEdge:ALEdgeRight]; + + XCTAssertEqual([[excludingRight objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[excludingRight objectAtIndex:1] firstAttribute], NSLayoutAttributeLeft); + XCTAssertEqual([[excludingRight objectAtIndex:2] firstAttribute], NSLayoutAttributeBottom); + + PL__NSArray_of(NSLayoutConstraint *) *excludingTrailing = [self.viewA autoPinEdgesToSuperviewEdgesWithInsets:ALEdgeInsetsZero excludingEdge:ALEdgeTrailing]; + + XCTAssertEqual([[excludingTrailing objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[excludingTrailing objectAtIndex:1] firstAttribute], NSLayoutAttributeLeading); + XCTAssertEqual([[excludingTrailing objectAtIndex:2] firstAttribute], NSLayoutAttributeBottom); +} + +#if PL__PureLayout_MinBaseSDK_iOS_8_0 + +-(void)testAutoPinEdgesSuperViewMarginsReturnsConstraintsCounterclockwiseFromTop +{ + PL__NSArray_of(NSLayoutConstraint *)*constraints = [self.viewA autoPinEdgesToSuperviewMarginsWithInsets:(ALEdgeInsetsZero)]; + + XCTAssertEqual([[constraints objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[constraints objectAtIndex:1] firstAttribute], NSLayoutAttributeLeading); + XCTAssertEqual([[constraints objectAtIndex:2] firstAttribute], NSLayoutAttributeBottom); + XCTAssertEqual([[constraints objectAtIndex:3] firstAttribute], NSLayoutAttributeTrailing); +} + +-(void)testAutoPinEdgesToSuperviewMarginsExcludingEdgeRetainsRelativeConstraintOrdering +{ + PL__NSArray_of(NSLayoutConstraint *)*constraints = [self.viewA autoPinEdgesToSuperviewMarginsExcludingEdge:ALEdgeLeading]; + + XCTAssertEqual([[constraints objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[constraints objectAtIndex:1] firstAttribute], NSLayoutAttributeBottom); + XCTAssertEqual([[constraints objectAtIndex:2] firstAttribute], NSLayoutAttributeTrailing); +} + +-(void)testAutoPinMarginsExcludingLeftEdgeDoesNotUseTrailing +{ + PL__NSArray_of(NSLayoutConstraint *) *excludingLeft = [self.viewA autoPinEdgesToSuperviewMarginsExcludingEdge:ALEdgeLeft]; + + XCTAssertEqual([[excludingLeft objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[excludingLeft objectAtIndex:1] firstAttribute], NSLayoutAttributeBottom); + XCTAssertEqual([[excludingLeft objectAtIndex:2] firstAttribute], NSLayoutAttributeRight); + + PL__NSArray_of(NSLayoutConstraint *) *excludingLeading = [self.viewA autoPinEdgesToSuperviewMarginsExcludingEdge:ALEdgeLeading]; + + XCTAssertEqual([[excludingLeading objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[excludingLeading objectAtIndex:1] firstAttribute], NSLayoutAttributeBottom); + XCTAssertEqual([[excludingLeading objectAtIndex:2] firstAttribute], NSLayoutAttributeTrailing); +} + +-(void)testAutoPinMarginsExcludingRightEdgeDoesNotUseLeading +{ + PL__NSArray_of(NSLayoutConstraint *) *excludingRight = [self.viewA autoPinEdgesToSuperviewMarginsExcludingEdge:ALEdgeRight]; + + XCTAssertEqual([[excludingRight objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[excludingRight objectAtIndex:1] firstAttribute], NSLayoutAttributeLeft); + XCTAssertEqual([[excludingRight objectAtIndex:2] firstAttribute], NSLayoutAttributeBottom); + + PL__NSArray_of(NSLayoutConstraint *) *excludingTrailing = [self.viewA autoPinEdgesToSuperviewMarginsExcludingEdge:ALEdgeTrailing]; + + XCTAssertEqual([[excludingTrailing objectAtIndex:0] firstAttribute], NSLayoutAttributeTop); + XCTAssertEqual([[excludingTrailing objectAtIndex:1] firstAttribute], NSLayoutAttributeLeading); + XCTAssertEqual([[excludingTrailing objectAtIndex:2] firstAttribute], NSLayoutAttributeBottom); +} + +#endif /* PL__PureLayout_MinBaseSDK_iOS_8_0 */ + @end diff --git a/PureLayout/PureLayoutTests/PureLayoutPriorityTests.m b/PureLayout/PureLayoutTests/PureLayoutPriorityTests.m index b21d211..1437ea6 100644 --- a/PureLayout/PureLayoutTests/PureLayoutPriorityTests.m +++ b/PureLayout/PureLayoutTests/PureLayoutPriorityTests.m @@ -14,18 +14,6 @@ @interface PureLayoutPriorityTests : PureLayoutTestBase @implementation PureLayoutPriorityTests -- (void)setUp -{ - [super setUp]; - -} - -- (void)tearDown -{ - - [super tearDown]; -} - /** Returns an array of the default priorities to test. */ @@ -38,7 +26,7 @@ - (void)tearDown A helper method that takes a block containing a call to the PureLayout API which adds one constraint, and calls -[assertConstraint:isAddedWithPriority:] for each of the default priorities. */ -- (void)assertConstraintIsAddedWithDefaultPriorities:(NSLayoutConstraint *(^)())block +- (void)assertConstraintIsAddedWithDefaultPriorities:(NSLayoutConstraint *(^)(void))block { for (NSNumber *layoutPriority in [self defaultPriorities]) { [self assertConstraint:block isAddedWithPriority:[layoutPriority floatValue]]; @@ -49,7 +37,7 @@ - (void)assertConstraintIsAddedWithDefaultPriorities:(NSLayoutConstraint *(^)()) A helper method that takes a block containing one or more calls to the PureLayout API which add multiple constraints, and calls -[assertConstraints:areAddedWithPriority:] for each of the default priorities. */ -- (void)assertConstraintsAreAddedWithDefaultPriorities:(NSArray *(^)())block +- (void)assertConstraintsAreAddedWithDefaultPriorities:(NSArray *(^)(void))block { for (NSNumber *layoutPriority in [self defaultPriorities]) { [self assertConstraints:block areAddedWithPriority:[layoutPriority floatValue]]; @@ -61,7 +49,7 @@ - (void)assertConstraintsAreAddedWithDefaultPriorities:(NSArray *(^)())block and verifies that when the +[NSLayoutConstraint autoSetPriority:forConstraints:] method is used, this one constraint is added with the correct priority specified. */ -- (void)assertConstraint:(NSLayoutConstraint *(^)())block isAddedWithPriority:(ALLayoutPriority)priority +- (void)assertConstraint:(NSLayoutConstraint *(^)(void))block isAddedWithPriority:(ALLayoutPriority)priority { [self assertConstraints:^PL__NSArray_of(NSLayoutConstraint *) *{ return @[block()]; } areAddedWithPriority:priority]; } @@ -71,7 +59,7 @@ - (void)assertConstraint:(NSLayoutConstraint *(^)())block isAddedWithPriority:(A constraints, and verifies that when the +[NSLayoutConstraint autoSetPriority:forConstraints:] method is used, these constraints are added with the correct priority specified. */ -- (void)assertConstraints:(PL__NSArray_of(NSLayoutConstraint *) *(^)())block areAddedWithPriority:(ALLayoutPriority)priority +- (void)assertConstraints:(PL__NSArray_of(NSLayoutConstraint *) *(^)(void))block areAddedWithPriority:(ALLayoutPriority)priority { __block PL__NSArray_of(NSLayoutConstraint *) *constraints; [NSLayoutConstraint autoSetPriority:priority forConstraints:^{ diff --git a/PureLayout/PureLayoutTests/PureLayoutRemovalTests.m b/PureLayout/PureLayoutTests/PureLayoutRemovalTests.m index c0bb830..50cecae 100644 --- a/PureLayout/PureLayoutTests/PureLayoutRemovalTests.m +++ b/PureLayout/PureLayoutTests/PureLayoutRemovalTests.m @@ -14,18 +14,6 @@ @interface PureLayoutRemovalTests : PureLayoutTestBase @implementation PureLayoutRemovalTests -- (void)setUp -{ - [super setUp]; - -} - -- (void)tearDown -{ - - [super tearDown]; -} - /** Test the +[removeConstraint:] method on UIView. Test the case where we're removing a constraint that was added to the closest common superview of the two views it diff --git a/PureLayout/PureLayoutTests/PureLayoutTestBase.m b/PureLayout/PureLayoutTests/PureLayoutTestBase.m index 53c94da..3934930 100644 --- a/PureLayout/PureLayoutTests/PureLayoutTestBase.m +++ b/PureLayout/PureLayoutTests/PureLayoutTestBase.m @@ -24,12 +24,6 @@ - (void)setUp [self setupViewHierarchy]; } -- (void)tearDown -{ - - [super tearDown]; -} - /** Sets up the default view hierarchy for tests. Test subclasses may override this method to customize the view hierarchy set up. */ diff --git a/PureLayout/PureLayoutTests/PureLayoutTests-iOS/PureLayoutPriorityTests-iOS.m b/PureLayout/PureLayoutTests/PureLayoutTests-iOS/PureLayoutPriorityTests-iOS.m index 12fc47b..3876897 100644 --- a/PureLayout/PureLayoutTests/PureLayoutTests-iOS/PureLayoutPriorityTests-iOS.m +++ b/PureLayout/PureLayoutTests/PureLayoutTests-iOS/PureLayoutPriorityTests-iOS.m @@ -40,7 +40,7 @@ - (void)tearDown A helper method that takes a block containing a call to the PureLayout API which adds one constraint, and calls -[assertConstraint:isAddedWithPriority:] for each of the default priorities. */ -- (void)assertConstraintIsAddedWithDefaultPriorities:(NSLayoutConstraint *(^)())block +- (void)assertConstraintIsAddedWithDefaultPriorities:(NSLayoutConstraint *(^)(void))block { for (NSNumber *layoutPriority in [self defaultPriorities]) { [self assertConstraint:block isAddedWithPriority:[layoutPriority floatValue]]; @@ -51,7 +51,7 @@ - (void)assertConstraintIsAddedWithDefaultPriorities:(NSLayoutConstraint *(^)()) A helper method that takes a block containing one or more calls to the PureLayout API which add multiple constraints, and calls -[assertConstraints:areAddedWithPriority:] for each of the default priorities. */ -- (void)assertConstraintsAreAddedWithDefaultPriorities:(PL__NSArray_of(NSLayoutConstraint *) *(^)())block +- (void)assertConstraintsAreAddedWithDefaultPriorities:(PL__NSArray_of(NSLayoutConstraint *) *(^)(void))block { for (NSNumber *layoutPriority in [self defaultPriorities]) { [self assertConstraints:block areAddedWithPriority:[layoutPriority floatValue]]; @@ -63,7 +63,7 @@ - (void)assertConstraintsAreAddedWithDefaultPriorities:(PL__NSArray_of(NSLayoutC and verifies that when the +[NSLayoutConstraint autoSetPriority:forConstraints:] method is used, this one constraint is added with the correct priority specified. */ -- (void)assertConstraint:(NSLayoutConstraint *(^)())block isAddedWithPriority:(ALLayoutPriority)priority +- (void)assertConstraint:(NSLayoutConstraint *(^)(void))block isAddedWithPriority:(ALLayoutPriority)priority { [self assertConstraints:^PL__NSArray_of(NSLayoutConstraint *) *{ return @[block()]; } areAddedWithPriority:priority]; } @@ -73,7 +73,7 @@ - (void)assertConstraint:(NSLayoutConstraint *(^)())block isAddedWithPriority:(A constraints, and verifies that when the +[NSLayoutConstraint autoSetPriority:forConstraints:] method is used, these constraints are added with the correct priority specified. */ -- (void)assertConstraints:(PL__NSArray_of(NSLayoutConstraint *) *(^)())block areAddedWithPriority:(ALLayoutPriority)priority +- (void)assertConstraints:(PL__NSArray_of(NSLayoutConstraint *) *(^)(void))block areAddedWithPriority:(ALLayoutPriority)priority { __block PL__NSArray_of(NSLayoutConstraint *) *constraints; [NSLayoutConstraint autoSetPriority:priority forConstraints:^{ @@ -117,28 +117,28 @@ - (void)testPriorityForContentCompressionResistanceAndContentHugging /** Test setting the priority of constraints that pin views to the view controller layout guides. */ -- (void)testPriorityForPinningToLayoutGuides -{ - UIViewController *viewController = [[UIViewController alloc] initWithNibName:nil bundle:nil]; - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - self.window.rootViewController = viewController; - [self.window makeKeyAndVisible]; - - // Wait until the next run loop to run the actual tests, after the window & view controller have a chance to - // get into a state where the view hierarchy is prepared to accept constraints to the layout guides - dispatch_async(dispatch_get_main_queue(), ^{ - [self assertConstraintIsAddedWithDefaultPriorities:^NSLayoutConstraint *{ - return [self.viewA autoPinToTopLayoutGuideOfViewController:viewController withInset:50.0]; - }]; - - [self assertConstraintIsAddedWithDefaultPriorities:^NSLayoutConstraint *{ - return [self.viewA autoPinToTopLayoutGuideOfViewController:viewController withInset:0.0]; - }]; - - [self assertConstraintIsAddedWithDefaultPriorities:^NSLayoutConstraint *{ - return [self.viewA autoPinToBottomLayoutGuideOfViewController:viewController withInset:-5.0]; - }]; - }); -} +//- (void)testPriorityForPinningToLayoutGuides +//{ +// UIViewController *viewController = [[UIViewController alloc] initWithNibName:nil bundle:nil]; +// self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; +// self.window.rootViewController = viewController; +// [self.window makeKeyAndVisible]; +// +// // Wait until the next run loop to run the actual tests, after the window & view controller have a chance to +// // get into a state where the view hierarchy is prepared to accept constraints to the layout guides +// dispatch_async(dispatch_get_main_queue(), ^{ +// [self assertConstraintIsAddedWithDefaultPriorities:^NSLayoutConstraint *{ +// return [self.viewA autoPinToTopLayoutGuideOfViewController:viewController withInset:50.0]; +// }]; +// +// [self assertConstraintIsAddedWithDefaultPriorities:^NSLayoutConstraint *{ +// return [self.viewA autoPinToTopLayoutGuideOfViewController:viewController withInset:0.0]; +// }]; +// +// [self assertConstraintIsAddedWithDefaultPriorities:^NSLayoutConstraint *{ +// return [self.viewA autoPinToBottomLayoutGuideOfViewController:viewController withInset:-5.0]; +// }]; +// }); +//} @end diff --git a/PureLayout/Supporting Files/PureLayout_Mac/Info.plist b/PureLayout/Supporting Files/PureLayout_Mac/Info.plist index dc2b99a..19c1e8d 100644 --- a/PureLayout/Supporting Files/PureLayout_Mac/Info.plist +++ b/PureLayout/Supporting Files/PureLayout_Mac/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.0.1 + 3.1 CFBundleSignature ???? CFBundleVersion diff --git a/PureLayout/Supporting Files/PureLayout_iOS/Info.plist b/PureLayout/Supporting Files/PureLayout_iOS/Info.plist index dc2b99a..19c1e8d 100644 --- a/PureLayout/Supporting Files/PureLayout_iOS/Info.plist +++ b/PureLayout/Supporting Files/PureLayout_iOS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.0.1 + 3.1 CFBundleSignature ???? CFBundleVersion diff --git a/PureLayout/Supporting Files/PureLayout_tvOS/Info.plist b/PureLayout/Supporting Files/PureLayout_tvOS/Info.plist index dc2b99a..19c1e8d 100644 --- a/PureLayout/Supporting Files/PureLayout_tvOS/Info.plist +++ b/PureLayout/Supporting Files/PureLayout_tvOS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.0.1 + 3.1 CFBundleSignature ???? CFBundleVersion diff --git a/README.md b/README.md index 8934035..4638d03 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # [![PureLayout](https://github.com/PureLayout/PureLayout/blob/master/Images/PureLayout.png?raw=true)](#) -[![Build Status](http://img.shields.io/travis/PureLayout/PureLayout.svg?style=flat)](https://travis-ci.org/PureLayout/PureLayout) [![Test Coverage](http://img.shields.io/coveralls/PureLayout/PureLayout.svg?style=flat)](https://coveralls.io/r/PureLayout/PureLayout) [![Version](http://img.shields.io/cocoapods/v/PureLayout.svg?style=flat)](http://cocoapods.org/pods/PureLayout) [![Platform](http://img.shields.io/cocoapods/p/PureLayout.svg?style=flat)](http://cocoapods.org/pods/PureLayout) [![License](http://img.shields.io/cocoapods/l/PureLayout.svg?style=flat)](LICENSE) +[![Build Status](https://travis-ci.org/PureLayout/PureLayout.svg?branch=master)](https://travis-ci.org/PureLayout/PureLayout) [![Version](http://img.shields.io/cocoapods/v/PureLayout.svg?style=flat)](http://cocoapods.org/pods/PureLayout) [![Platform](http://img.shields.io/cocoapods/p/PureLayout.svg?style=flat)](http://cocoapods.org/pods/PureLayout) [![License](http://img.shields.io/cocoapods/l/PureLayout.svg?style=flat)](LICENSE) The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. PureLayout extends `UIView`/`NSView`, `NSArray`, and `NSLayoutConstraint` with a comprehensive Auto Layout API that is modeled after Apple's own frameworks. PureLayout is a cross-platform Objective-C library that works (and looks!) great in Swift. It is fully backwards-compatible with all versions of iOS and OS X that support Auto Layout. @@ -97,7 +97,7 @@ There are 5 specific attribute types, which are used throughout most of the API: Additionally, there is one generic attribute type, `ALAttribute`, which is effectively a union of all the specific types. You can think of this as the "supertype" of all of the specific attribute types, which means that it is always safe to cast a specific type to the generic `ALAttribute` type. (Note that the reverse is not true -- casting a generic ALAttribute to a specific attribute type is unsafe!) -### [`UIView`/`NSView`](PureLayout/PureLayout/ALView%2BPureLayout.h) +### [`UIView`/`NSView`](PureLayout/PureLayout/include/ALView%2BPureLayout.h) ``` - autoSetContent(CompressionResistance|Hugging)PriorityForAxis: - autoCenterInSuperview(Margins) // Margins variant iOS 8.0+ only @@ -110,9 +110,11 @@ Additionally, there is one generic attribute type, `ALAttribute`, which is effec - autoSetDimension(s)ToSize: - autoConstrainAttribute:toAttribute:ofView:(withOffset:|withMultiplier:) - autoPinTo(Top|Bottom)LayoutGuideOfViewController:withInset: // iOS only +- autoPinEdgeToSuperviewSafeArea: // iOS 11.0+ only +- autoPinEdgeToSuperviewSafeArea:withInset: // iOS 11.0+ only ``` -### [`NSArray`](PureLayout/PureLayout/NSArray%2BPureLayout.h) +### [`NSArray`](PureLayout/PureLayout/include/NSArray%2BPureLayout.h) ``` // Arrays of Constraints - autoInstallConstraints @@ -129,7 +131,7 @@ Additionally, there is one generic attribute type, `ALAttribute`, which is effec - autoDistributeViewsAlongAxis:alignedTo:withFixedSize:(insetSpacing:) ``` -### [`NSLayoutConstraint`](PureLayout/PureLayout/NSLayoutConstraint%2BPureLayout.h) +### [`NSLayoutConstraint`](PureLayout/PureLayout/include/NSLayoutConstraint%2BPureLayout.h) ``` + autoCreateAndInstallConstraints: + autoCreateConstraintsWithoutInstalling: @@ -144,16 +146,28 @@ Additionally, there is one generic attribute type, `ALAttribute`, which is effec ### Sample Code (Swift) PureLayout dramatically simplifies writing Auto Layout code. Let's take a quick look at some examples, using PureLayout from Swift. +Initialize the view using PureLayout initializer: + +```swift +let view1 = UIView(forAutoLayout: ()) +``` + +If you need to use a different initializer (e.g. in `UIView` subclass), you can also use `configureForAutoLayout`: + +``` +view1.configureForAutoLayout() // alternative to UIView.init(forAutoLayout: ()) +``` + Here's a constraint between two views created (and automatically activated) using PureLayout: ```swift -view1.autoPinEdge(.Top, toEdge: .Bottom, ofView: view2) +view1.autoPinEdge(.top, toEdge: .bottom, ofView: view2) ``` Without PureLayout, here's the equivalent code you'd have to write using Apple's Foundation API directly: ```swift -NSLayoutConstraint(item: view1, attribute: .Top, relatedBy: .Equal, toItem: view2, attribute: .Bottom, multiplier: 1.0, constant: 0.0).active = true +NSLayoutConstraint(item: view1, attribute: .top, relatedBy: .equal, toItem: view2, attribute: .bottom, multiplier: 1.0, constant: 0.0).active = true ``` Many APIs of PureLayout create multiple constraints for you under the hood, letting you write highly readable layout code: @@ -163,13 +177,19 @@ Many APIs of PureLayout create multiple constraints for you under the hood, lett logoImageView.autoCenterInSuperview() // 4 constraints created & activated in one line! -textContentView.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsets(top: 20.0, left: 5.0, bottom: 10.0, right: 5.0)) +textContentView.autoPinEdgesToSuperviewEdges(with insets: UIEdgeInsets(top: 20.0, left: 5.0, bottom: 10.0, right: 5.0)) ``` PureLayout always returns the constraints it creates so you have full control: ```swift -let constraint = skinnyView.autoMatchDimension(.Height, toDimension: .Width, ofView: tallView) +let constraint = skinnyView.autoMatchDimension(.height, toDimension: .width, ofView: tallView) +``` + +PureLayout supports safearea with iOS 11.0+: + +```swift +view2.autoPinEdge(toSuperviewSafeArea: .top) ``` PureLayout supports all Auto Layout features including inequalities, priorities, layout margins, identifiers, and much more. It's a comprehensive, developer-friendly way to use Auto Layout. @@ -192,7 +212,7 @@ There are quite a few different ways to implement Auto Layout. Here is a quick o * Apple [NSLayoutConstraint SDK API](https://developer.apple.com/library/ios/documentation/AppKit/Reference/NSLayoutConstraint_Class/index.html#//apple_ref/occ/clm/NSLayoutConstraint/constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:) * Pros: Raw power * Cons: Extremely verbose; tedious to write; difficult to read -* Apple [Visual Format Language](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage/VisualFormatLanguage.html) +* Apple [Visual Format Language](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage.html) * Pros: Concise; convenient * Cons: Doesn't support some use cases; lacks compile-time checking and safety; must learn syntax; hard to debug * Apple Interface Builder