From 38dc9208231920d8a1f6b436b788a83563a60976 Mon Sep 17 00:00:00 2001 From: Keith Harrison Date: Fri, 25 Mar 2016 11:29:54 +0000 Subject: [PATCH 001/159] Adopt Swift 2.2 selector syntax --- AutoLayout/AutoLayout/LayoutGuideController.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/AutoLayout/AutoLayout/LayoutGuideController.swift b/AutoLayout/AutoLayout/LayoutGuideController.swift index 28ce349..caaee87 100644 --- a/AutoLayout/AutoLayout/LayoutGuideController.swift +++ b/AutoLayout/AutoLayout/LayoutGuideController.swift @@ -66,14 +66,16 @@ class LayoutGuideController: UIViewController { let redImage = UIImage(named: "redButton") noButton.setBackgroundImage(redImage, forState: .Normal) noButton.contentEdgeInsets = UIEdgeInsetsMake(8, 16, 8, 16) - noButton.addTarget(self, action: "noThanks:", forControlEvents: .TouchUpInside) + let noThanksAction = #selector(LayoutGuideController.noThanks(_:)) + noButton.addTarget(self, action: noThanksAction, forControlEvents: .TouchUpInside) yesButton.translatesAutoresizingMaskIntoConstraints = false yesButton.setTitle("Yes please!", forState: .Normal) let greenImage = UIImage(named: "greenButton") yesButton.setBackgroundImage(greenImage, forState: .Normal) yesButton.contentEdgeInsets = UIEdgeInsetsMake(8, 16, 8, 16) - yesButton.addTarget(self, action: "yesPlease:", forControlEvents: .TouchUpInside) + let yesPleaseAction = #selector(LayoutGuideController.yesPlease(_:)) + yesButton.addTarget(self, action: yesPleaseAction, forControlEvents: .TouchUpInside) view.addSubview(noButton) view.addSubview(yesButton) From 14d4ad26732034cecd565861652159125309fe42 Mon Sep 17 00:00:00 2001 From: Keith Harrison Date: Fri, 25 Mar 2016 11:52:12 +0000 Subject: [PATCH 002/159] Updated by Xcode 7.3 --- AutoLayout/AutoLayout/Base.lproj/Main.storyboard | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AutoLayout/AutoLayout/Base.lproj/Main.storyboard b/AutoLayout/AutoLayout/Base.lproj/Main.storyboard index c689bb2..88f4933 100644 --- a/AutoLayout/AutoLayout/Base.lproj/Main.storyboard +++ b/AutoLayout/AutoLayout/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + From 94fa50dc8bb59c0ec1b497d1cf95ef205571e4d4 Mon Sep 17 00:00:00 2001 From: Keith Harrison Date: Fri, 25 Mar 2016 13:47:37 +0000 Subject: [PATCH 003/159] Layout Guides --- AutoLayout/AutoLayout/Base.lproj/Main.storyboard | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutoLayout/AutoLayout/Base.lproj/Main.storyboard b/AutoLayout/AutoLayout/Base.lproj/Main.storyboard index 88f4933..f7a2421 100644 --- a/AutoLayout/AutoLayout/Base.lproj/Main.storyboard +++ b/AutoLayout/AutoLayout/Base.lproj/Main.storyboard @@ -136,7 +136,7 @@ - diff --git a/AutoLayout/AutoLayout/Info.plist b/AutoLayout/AutoLayout/Info.plist index fd1ab7c..3c0e24f 100644 --- a/AutoLayout/AutoLayout/Info.plist +++ b/AutoLayout/AutoLayout/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 1.4 CFBundleSignature ???? CFBundleVersion - 1 + 4 LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/AutoLayout/README.md b/AutoLayout/README.md index 453c261..af9336a 100644 --- a/AutoLayout/README.md +++ b/AutoLayout/README.md @@ -7,15 +7,19 @@ Auto Layout examples using Interface Builder and in code. + Proportional spacing using a stack view + Layout Anchors + Layout Guides as spacer views ++ Adaptive constraints using Interface Builder and code See the following posts further details: + [Proportional Spacing with Auto Layout](http://useyourloaf.com/blog/proportional-spacing-with-auto-layout/) + [Adapting Images for Size Classes](http://useyourloaf.com/blog/adapting-images-for-size-classes/) + [Pain Free Constraints with Layout Anchors](http://useyourloaf.com/blog/pain-free-constraints-with-layout-anchors/) ++ [Goodbye Spacer Views Hello Layout Guides](http://useyourloaf.com/blog/goodbye-spacer-views-hello-layout-guides/) ++ [Adapting AutoLayout Without Interface Builder](http://useyourloaf.com/blog/adapting-auto-layout-without-interface-builder/) #### Version History ++ Version 1.4 28 Mar 2016 Adapting constraints to size classes + Version 1.3 27 Feb 2016 Using layout guides to space views + Version 1.2 22 Feb 2016 Example of using layout anchors + Version 1.1 31 Jan 2016 Custom Asset catalog for size classes. From 4d65e6ffe0163328cedbc85915591b57e51b523e Mon Sep 17 00:00:00 2001 From: Keith Harrison Date: Mon, 4 Apr 2016 21:51:25 +0100 Subject: [PATCH 005/159] Add contentMode playground --- .../Bottom.xcplaygroundpage/Contents.swift | 15 +++++++++ .../timeline.xctimeline | 11 +++++++ .../Contents.swift | 14 ++++++++ .../timeline.xctimeline | 11 +++++++ .../Contents.swift | 14 ++++++++ .../timeline.xctimeline | 11 +++++++ .../Center.xcplaygroundpage/Contents.swift | 15 +++++++++ .../timeline.xctimeline | 21 ++++++++++++ .../Left.xcplaygroundpage/Contents.swift | 14 ++++++++ .../Left.xcplaygroundpage/timeline.xctimeline | 11 +++++++ .../Redraw.xcplaygroundpage/Contents.swift | 18 +++++++++++ .../timeline.xctimeline | 21 ++++++++++++ .../Right.xcplaygroundpage/Contents.swift | 14 ++++++++ .../timeline.xctimeline | 11 +++++++ .../Contents.swift | 30 ++++++++++++++++++ .../timeline.xctimeline | 16 ++++++++++ .../Contents.swift | 14 ++++++++ .../timeline.xctimeline | 11 +++++++ .../Contents.swift | 17 ++++++++++ .../timeline.xctimeline | 11 +++++++ .../Pages/Top.xcplaygroundpage/Contents.swift | 15 +++++++++ .../Top.xcplaygroundpage/timeline.xctimeline | 11 +++++++ .../TopLeft.xcplaygroundpage/Contents.swift | 14 ++++++++ .../timeline.xctimeline | 11 +++++++ .../TopRight.xcplaygroundpage/Contents.swift | 14 ++++++++ .../timeline.xctimeline | 11 +++++++ .../Contents.swift | 29 +++++++++++++++++ .../Resources/star100.png | Bin 0 -> 1306 bytes .../Sources/CircleView.swift | 22 +++++++++++++ .../Sources/StarView.swift | 21 ++++++++++++ .../contents.xcplayground | 19 +++++++++++ .../contents.xcworkspacedata | 7 ++++ 32 files changed, 474 insertions(+) create mode 100644 Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/timeline.xctimeline create mode 100644 Playgrounds/ContentMode.playground/Pages/contentMode.xcplaygroundpage/Contents.swift create mode 100644 Playgrounds/ContentMode.playground/Resources/star100.png create mode 100644 Playgrounds/ContentMode.playground/Sources/CircleView.swift create mode 100644 Playgrounds/ContentMode.playground/Sources/StarView.swift create mode 100644 Playgrounds/ContentMode.playground/contents.xcplayground create mode 100644 Playgrounds/ContentMode.playground/playground.xcworkspace/contents.xcworkspacedata diff --git a/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..24abc4e --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/Contents.swift @@ -0,0 +1,15 @@ +import UIKit +import XCPlayground +/*: + ### Bottom + + Fix the position of the content. Does not scale + or stretch the content. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .Bottom +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..f4e4340 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..1bb2c89 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/Contents.swift @@ -0,0 +1,14 @@ +import UIKit +import XCPlayground +/*: + ### Bottom Left + Fix the position of the content. Does not scale + or stretch the content. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .BottomLeft +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..750a3a3 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..f3442e5 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/Contents.swift @@ -0,0 +1,14 @@ +import UIKit +import XCPlayground +/*: + ### Bottom Right + Fix the position of the content. Does not scale + or stretch the content. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .BottomRight +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..e2347be --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..a7cbc6e --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/Contents.swift @@ -0,0 +1,15 @@ +import UIKit +import XCPlayground +/*: + ### Center + + Fix the position of the content. Does not scale + or stretch the content. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .Center +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..5e04c90 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..4844811 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/Contents.swift @@ -0,0 +1,14 @@ +import UIKit +import XCPlayground +/*: + ### Left + Fix the position of the content. Does not scale + or stretch the content. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .Left +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..da653f9 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..8486cfd --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/Contents.swift @@ -0,0 +1,18 @@ +import UIKit +import XCPlayground +/*: + ### Redraw + + Use this mode when you have a custom view that implements drawRect. + + When the bounds of the view change the view will be redrawn by + calling drawRect. + */ +let myView = CircleView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.backgroundColor = .whiteColor() +myView.contentMode = .Redraw +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) \ No newline at end of file diff --git a/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..c8b56ae --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..e87045f --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/Contents.swift @@ -0,0 +1,14 @@ +import UIKit +import XCPlayground +/*: + ### Right + Fix the position of the content. Does not scale + or stretch the content. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .Right +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..52f2979 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..8788d5e --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/Contents.swift @@ -0,0 +1,30 @@ +import UIKit +import XCPlayground +/*: + ### Scale Aspect Fill + `ScaleAspectFill` scales the content to totally fill the view maintaining the aspect ratio. This can result in the content being larger than the bounds of the view. + + */ +let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400)) +containerView.backgroundColor = .redColor() + +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +containerView.addSubview(myView) +myView.center = CGPoint(x: 200, y: 200) + +myView.starImageView.contentMode = .ScaleAspectFill +/*: + #### clipToBounds + You will most likely want to have the superview set to clip subviews + to bounds to prevent the scaled view from being visible outside the + super view. + + Try changing the following setting to see the difference. + */ +myView.clipsToBounds = true + +containerView +XCPlaygroundPage.currentPage.liveView = containerView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..ec83354 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..daae1d1 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/Contents.swift @@ -0,0 +1,14 @@ +import UIKit +import XCPlayground +/*: + ### Scale Aspect Fit + + `ScaleAspectFit` scales the content to fit the view but maintains the aspect ratio. Any part of the view bounds that is not filled with content is transparent. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .ScaleAspectFit +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..61b3e15 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..5e6608e --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/Contents.swift @@ -0,0 +1,17 @@ +import UIKit +import XCPlayground +/*: + ### Scale To Fill + + This is the default mode. + + The image is stretched in both dimensions to fill the frame. The + aspect ratio of the image is not maintained. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .ScaleToFill +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..07c1389 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..e96706e --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/Contents.swift @@ -0,0 +1,15 @@ +import UIKit +import XCPlayground +/*: + ### Top + + Fix the position of the content. Does not scale + or stretch the content. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .Top +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..0e86698 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..5fdbfd4 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/Contents.swift @@ -0,0 +1,14 @@ +import UIKit +import XCPlayground +/*: + ### Top Left + Fix the position of the content. Does not scale + or stretch the content. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .TopLeft +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..bfa3c3c --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..330506c --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/Contents.swift @@ -0,0 +1,14 @@ +import UIKit +import XCPlayground +/*: + ### Top Right + Fix the position of the content. Does not scale + or stretch the content. + */ +let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) +myView.starImageView.contentMode = .TopRight +myView +XCPlaygroundPage.currentPage.liveView = myView +//: [Previous](@previous) +//: [Index](contentMode) +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/timeline.xctimeline new file mode 100644 index 0000000..5490561 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Playgrounds/ContentMode.playground/Pages/contentMode.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/contentMode.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..04412dc --- /dev/null +++ b/Playgrounds/ContentMode.playground/Pages/contentMode.xcplaygroundpage/Contents.swift @@ -0,0 +1,29 @@ +/*: + ### UIView contentMode Quick Guide + +The `contentMode` property of UIView allows you to control how to layout a view when the view's bounds change. The system will not, by default, redraw a view each time the bounds change. That would be wasteful. Instead, depending on the content mode, it can scale, stretch or pin the contents to a fixed position. + + There are thirteen different content modes but it is easiest to think of three main groups based on the effect: + + #### Scaling the View (with or without maintaining the aspect ratio) + ++ [Scale To Fill](ScaleToFill) ++ [Scale Aspect Fit](ScaleAspectFit) ++ [Scale Aspect Fill](ScaleAspectFill) + + #### Redrawing the View + ++ [Redraw](Redraw) + + #### Positioning the View + ++ [Center](Center) ++ [Top](Top) ++ [Bottom](Bottom) ++ [Left](Left) ++ [Right](Right) ++ [TopLeft](TopLeft) ++ [TopRight](TopRight) ++ [BottomLeft](BottomLeft) ++ [BottomRight](BottomRight) +*/ diff --git a/Playgrounds/ContentMode.playground/Resources/star100.png b/Playgrounds/ContentMode.playground/Resources/star100.png new file mode 100644 index 0000000000000000000000000000000000000000..4965255dc5c56ab3d62c08ab371db50421bcb727 GIT binary patch literal 1306 zcmV+#1?BpQP)LRY? zN?hBWG1ke`=_CWu_^ahjSlgj4*UZrACj!y=r{qyp+oUYk&-U#B&FCrt(fXz2R8rcf zDb~{U?gGl`Eu!OBPTH#`)z!%8FP`IDOxms_)z|dx1I6evo8w+d+OZ+k+VkxM!{;@a z;$TJDwI9{n^6dq`=Q)((WJ1`u9n{_N?FPK(JQdUBrsPv<-H$ES%?r}-5!2~4*Tq@f zpnl(b>FW;O>KeM|K9%BQao&hc*{mwo(FoD=4$|#;-+-OtT*BuzD=U;$OYyJL2mWvE@gN;cIH$kh$hR-Rc|B=_ak^ONiibW!;qt z((<(CL~GrSujNUq+B3Y*u6N{ z!gt<+=j#yU>=Q88%H!)5E!NK9>lj+xpCZ-SRNJN3>L4D~+)vu78`R$?)zpmPY`5k? zj^Sz()aO6gyW{H=Y21+()8v!kWkJ}vzUDfX;$p$)H%8gCaNdbX*|NpxGjiUCMA^2? z=qpUxtqjudc;12N>kr51FxKiJh2V7V>?_vL@a+dS*TkgbRYTaf#OE~5=qXd$rl{mlR@w@5Sq2yTn&#c)100N## zL_t(|0qxj>dNeoy1<+gF+P3-Iwr$(0ZQEJnm3-mirOOnTeZ~Lkwd*(hAmHY~Tet7ry+>7R!|y+MxOHO;9LPU?>d|BB zvHi)@XU|{2){B?a>J{ucS4e$QyqMims^M1tB$5S6c@`$EfOfJ%lw-O=B1&oTiGVW=J_ec`dDw z^gNZ4+Oi<6IGa))-++SlwUpr70VSQAD6Fd+ih8zFP;@VpU7(;osOzU7AE+CkpyyC` zkAeoFY>1*BLD?`xjX>Ebg}nwFcJQ1d<|d;leh)wJW%hp+C@j*C#zL0e z6%DlX88OLO~Yiti7`v4*m8!=llT$e{x3Z{ysR>^9N^a@`Su&oE8#=5%a6fB!?8Uoa%y#ERwS=H})$2?F+@vwNYd Qm;e9(07*qoM6N<$f-6757XSbN literal 0 HcmV?d00001 diff --git a/Playgrounds/ContentMode.playground/Sources/CircleView.swift b/Playgrounds/ContentMode.playground/Sources/CircleView.swift new file mode 100644 index 0000000..9ca1165 --- /dev/null +++ b/Playgrounds/ContentMode.playground/Sources/CircleView.swift @@ -0,0 +1,22 @@ +import UIKit + +public class CircleView: UIView { + + var lineWidth: CGFloat = 5 { + didSet { setNeedsDisplay() } + } + + var color: UIColor = .redColor() { + didSet { setNeedsDisplay() } + } + + public override func drawRect(rect: CGRect) { + + let circleCenter = convertPoint(center, fromView: superview) + let circleRadius = min(bounds.size.width,bounds.size.height)/2 * 0.80 + let circlePath = UIBezierPath(arcCenter: circleCenter, radius: circleRadius, startAngle: 0, endAngle: CGFloat(2*M_PI), clockwise: true) + circlePath.lineWidth = lineWidth + color.set() + circlePath.stroke() + } +} diff --git a/Playgrounds/ContentMode.playground/Sources/StarView.swift b/Playgrounds/ContentMode.playground/Sources/StarView.swift new file mode 100644 index 0000000..d1bc0fe --- /dev/null +++ b/Playgrounds/ContentMode.playground/Sources/StarView.swift @@ -0,0 +1,21 @@ +import UIKit + +public class StarView: UIView { + + public let starImageView: UIImageView + + public override init(frame: CGRect) { + let starImage = UIImage(named: "star100") + starImageView = UIImageView(image: starImage) + + super.init(frame: frame) + addSubview(starImageView) + backgroundColor = .greenColor() + starImageView.frame = bounds + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + diff --git a/Playgrounds/ContentMode.playground/contents.xcplayground b/Playgrounds/ContentMode.playground/contents.xcplayground new file mode 100644 index 0000000..e759d69 --- /dev/null +++ b/Playgrounds/ContentMode.playground/contents.xcplayground @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Playgrounds/ContentMode.playground/playground.xcworkspace/contents.xcworkspacedata b/Playgrounds/ContentMode.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..5cbf448 --- /dev/null +++ b/Playgrounds/ContentMode.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + From 4b6942f45f69c3fb18ba8408239f92f449b4e595 Mon Sep 17 00:00:00 2001 From: Keith Harrison Date: Mon, 4 Apr 2016 21:58:00 +0100 Subject: [PATCH 006/159] Zip playground files --- Playgrounds/ContentMode.zip | Bin 0 -> 36587 bytes Playgrounds/String.zip | Bin 0 -> 11986 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Playgrounds/ContentMode.zip create mode 100644 Playgrounds/String.zip diff --git a/Playgrounds/ContentMode.zip b/Playgrounds/ContentMode.zip new file mode 100644 index 0000000000000000000000000000000000000000..464fa32bdb5ba5d172567b7e5da8e828571f64de GIT binary patch literal 36587 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 literal 0 HcmV?d00001 diff --git a/Playgrounds/String.zip b/Playgrounds/String.zip new file mode 100644 index 0000000000000000000000000000000000000000..64cb3fcb5cb958a2e6a3d24431bc195f015fc6b2 GIT binary patch literal 11986 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 Date: Mon, 11 Apr 2016 16:53:21 +0100 Subject: [PATCH 007/159] Add example of right-to-left language --- .../AutoLayout.xcodeproj/project.pbxproj | 8 ++ .../AutoLayout/Base.lproj/Main.storyboard | 120 +++++++++++++++--- AutoLayout/AutoLayout/Info.plist | 4 +- AutoLayout/AutoLayout/RTLViewController.swift | 69 ++++++++++ .../AutoLayout/ar.lproj/LaunchScreen.strings | 3 + AutoLayout/AutoLayout/ar.lproj/Main.strings | 78 ++++++++++++ AutoLayout/README.md | 3 + 7 files changed, 266 insertions(+), 19 deletions(-) create mode 100644 AutoLayout/AutoLayout/RTLViewController.swift create mode 100644 AutoLayout/AutoLayout/ar.lproj/LaunchScreen.strings create mode 100644 AutoLayout/AutoLayout/ar.lproj/Main.strings diff --git a/AutoLayout/AutoLayout.xcodeproj/project.pbxproj b/AutoLayout/AutoLayout.xcodeproj/project.pbxproj index e4e68bd..c2d60e9 100644 --- a/AutoLayout/AutoLayout.xcodeproj/project.pbxproj +++ b/AutoLayout/AutoLayout.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 5319D0191CA6E8C1009E4AFA /* AdaptiveViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5319D0181CA6E8C1009E4AFA /* AdaptiveViewController.swift */; }; 5329F1161C79008300A35954 /* LayoutAnchorController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5329F1151C79008300A35954 /* LayoutAnchorController.swift */; }; 53358D6F1C80F0B100C1842A /* LayoutGuideController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53358D6E1C80F0B100C1842A /* LayoutGuideController.swift */; }; + 535078741CBAD4D400700816 /* RTLViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535078731CBAD4D400700816 /* RTLViewController.swift */; }; 5362E7F81C53F1B200DAA88B /* CenterAlignViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5362E7F71C53F1B200DAA88B /* CenterAlignViewController.swift */; }; 53D6A5F11C53BF5200A81A14 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D6A5F01C53BF5200A81A14 /* AppDelegate.swift */; }; 53D6A5F31C53BF5200A81A14 /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D6A5F21C53BF5200A81A14 /* MasterViewController.swift */; }; @@ -26,6 +27,9 @@ 5319D0181CA6E8C1009E4AFA /* AdaptiveViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdaptiveViewController.swift; sourceTree = ""; }; 5329F1151C79008300A35954 /* LayoutAnchorController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutAnchorController.swift; sourceTree = ""; }; 53358D6E1C80F0B100C1842A /* LayoutGuideController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutGuideController.swift; sourceTree = ""; }; + 535078731CBAD4D400700816 /* RTLViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RTLViewController.swift; sourceTree = ""; }; + 535078751CBADA0C00700816 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Main.strings; sourceTree = ""; }; + 535078761CBADA0C00700816 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LaunchScreen.strings; sourceTree = ""; }; 5362E7F71C53F1B200DAA88B /* CenterAlignViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = CenterAlignViewController.swift; sourceTree = ""; tabWidth = 4; }; 53D6A5ED1C53BF5200A81A14 /* AutoLayout.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoLayout.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53D6A5F01C53BF5200A81A14 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -78,6 +82,7 @@ 53D6A5F01C53BF5200A81A14 /* AppDelegate.swift */, 53D6A5F21C53BF5200A81A14 /* MasterViewController.swift */, 5362E7F71C53F1B200DAA88B /* CenterAlignViewController.swift */, + 535078731CBAD4D400700816 /* RTLViewController.swift */, 5329F1151C79008300A35954 /* LayoutAnchorController.swift */, 53358D6E1C80F0B100C1842A /* LayoutGuideController.swift */, 53EDF4071C5D5C78009F91EA /* StackViewController.swift */, @@ -177,6 +182,7 @@ 53358D6F1C80F0B100C1842A /* LayoutGuideController.swift in Sources */, 5319D0191CA6E8C1009E4AFA /* AdaptiveViewController.swift in Sources */, 53EDF4081C5D5C78009F91EA /* StackViewController.swift in Sources */, + 535078741CBAD4D400700816 /* RTLViewController.swift in Sources */, 5329F1161C79008300A35954 /* LayoutAnchorController.swift in Sources */, 53EDF40C1C5D6641009F91EA /* UIViewController+addView.swift in Sources */, 5362E7F81C53F1B200DAA88B /* CenterAlignViewController.swift in Sources */, @@ -191,6 +197,7 @@ isa = PBXVariantGroup; children = ( 53D6A5F71C53BF5200A81A14 /* Base */, + 535078751CBADA0C00700816 /* ar */, ); name = Main.storyboard; sourceTree = ""; @@ -199,6 +206,7 @@ isa = PBXVariantGroup; children = ( 53D6A5FC1C53BF5200A81A14 /* Base */, + 535078761CBADA0C00700816 /* ar */, ); name = LaunchScreen.storyboard; sourceTree = ""; diff --git a/AutoLayout/AutoLayout/Base.lproj/Main.storyboard b/AutoLayout/AutoLayout/Base.lproj/Main.storyboard index 456e2a2..64d65bb 100644 --- a/AutoLayout/AutoLayout/Base.lproj/Main.storyboard +++ b/AutoLayout/AutoLayout/Base.lproj/Main.storyboard @@ -53,7 +53,7 @@ -