Stanford CS193p. Developing Applications for ios. Spring CS193p. Spring 2016

Similar documents
Stanford CS193p. Developing Applications for ios. Winter CS193p. Winter 2017

Stanford CS193p. Developing Applications for ios. Fall CS193p. Fall

Stanford CS193p. Developing Applications for ios. Winter CS193p! Winter 2015

View Controller Lifecycle

Stanford CS193p. Developing Applications for ios. Fall CS193p. Fall

Lecture 8 Demo Code: Cassini Multithreading

Stanford CS193p. Developing Applications for ios. Spring CS193p. Spring 2016

Stanford CS193p. Developing Applications for ios. Winter CS193p. Winter 2017

Developing Applications for ios

Stanford CS193p. Developing Applications for ios. Winter CS193p! Winter 2015

Developing Applications for ios

Stanford CS193p. Developing Applications for ios. Fall Stanford CS193p. Fall 2011

LESSONS LEARNED. SWIFT. Dagna Bieda, 7th April 2016

Stanford CS193p. Developing Applications for ios. Winter CS193p. Winter 2017

Objective-C. Stanford CS193p Fall 2013

Stanford CS193p. Developing Applications for ios. Winter CS193p! Winter 2015

ios Application Development Lecture 5: Protocols, Extensions,TabBar an Scroll Views

Assignment III: Graphing Calculator

Stanford CS193p. Developing Applications for ios. Fall CS193p. Fall

Assignment II: Calculator Brain

Stanford CS193p. Developing Applications for ios Fall Stanford CS193p. Fall 2013

lecture 10 UI/UX and Programmatic Design cs : spring 2018

Today s Topics. Scroll views Table views. UITableViewController Table view cells. Displaying data Controlling appearance & behavior

Stanford CS193p. Developing Applications for ios. Winter CS193p! Winter 2015

Assignment III: Graphing Calculator

CS193P - Lecture 8. iphone Application Development. Scroll Views & Table Views

Assignment III: Graphing Calculator

Assignment III: Graphing Calculator

Introductory ios Development

Stanford CS193p. Developing Applications for ios. Fall CS193p. Fall

Mobile Application Programming. Swift Classes

Mobile Application Programming. Swift Classes

iphone Application Programming Lecture 3: Swift Part 2

Stanford CS193p. Developing Applications for ios. Spring Stanford CS193p. Spring 2012

Stanford CS193p. Developing Applications for ios. Fall Stanford CS193p. Fall 2011

iphone Application Programming Lab 2: MVC and Delegation + A01 discussion

Stanford CS193p. Developing Applications for iphone 4, ipod Touch, & ipad Fall Stanford CS193p Fall 2010

View Concepts. iphone Application Programming Lecture 4: User Interface Design. SDK provide many types of Views to show your content

ios Mobile Development

What s New in imessage Apps

CS193p Spring 2010 Thursday, April 29, 2010

Stanford CS193p. Developing Applications for ios. Winter CS193p. Winter 2017

ios Mobile Development

Advanced ios. CSCI 4448/5448: Object-Oriented Analysis & Design Lecture 20 11/01/2012

Learn to make desktop LE

Announcements. Today s Topics

COMP : Practical 8 ActionScript II: The If statement and Variables

iphone Application Programming Lecture 3: Swift Part 2

S A M P L E C H A P T E R

Scroll View School Hands-On Challenges

Assignment IV: Smashtag Mentions

Mobile Application Programming. Layout Techniques

SWIFT! init(title: String) { self.title = title } // required initializer w/ named parameter

Designing iphone Applications

ios Mobile Development

ios Memory Deep Dive #WWDC18 Kyle Howarth, Software Engineer James Snee, Software Engineer Kris Markel, Software Engineer

Introductory ios Development

Assignment I: Concentration

Adaptive Layout Hands-On Challenges

ios DeCal : Lecture 2 Structure of ios Applications: MVC and Auto Layout

Mastering UIKit on tvos

Questions. Exams: no. Get by without own Mac? Why ios? ios vs Android restrictions. Selling in App store how hard to publish? Future of Objective-C?

ITP 342 Advanced Mobile App Dev. Memory

Intro. Scheme Basics. scm> 5 5. scm>

Programming ios in Lua A bridge story

Structuring an App Copyright 2013 Apple Inc. All Rights Reserved.

What s New in tvos 12

Mobile Development Lab 3

A Mad Libs app that you will navigate through 3 UIViewControllers to add text that will be shown in a story on the fourth UIViewController.

iphone Application Programming Lab 3: Swift Types and Custom Operator + A02 discussion

View Controllers CPRE 388

SWIFT - PROTOCOLS. Protocols also follow the similar syntax as that of classes, structures, and enumerations:

ios Application Development Lecture 2: Seminar and Unit 1

Stanford CS193p. Developing Applications for ios. Fall CS193p. Fall

Announcements. Lab 2 is due next Monday (Sept 25 th ) by 11:59 PM. Late policy is 10% of lab total per day late. So -7.5 points per day late for lab 2

let w = UIWindow(frame: UIScreen.mainScreen().bounds)

Announcement. Final Project Proposal Presentations and Updates

Mastering Drag and Drop

Xcode 6 and ios 8 What s New for Software Developers

iphone Programming Patrick H. Madden SUNY Binghamton Computer Science Department

Learn to make watchosle

Registering for the Apple Developer Program

Object-Oriented Programming in Objective-C

CS193E Lecture 7. Document-based Applications NSTableView Key-Value Coding

Tables. Mobile Application Development in ios School of EECS Washington State University Instructor: Larry Holder

ITP 342 Mobile App Dev. Table Views

What's New in UIKit Dynamics and Visual Effects Session 229

Mobile Application Development

Mobile Application Programming. Controls

Chapter 6 Introduction to Defining Classes

Enhancing your apps for the next dimension of touch

Assignment II: Foundation Calculator

ITP 342 Mobile App Dev. Collection View

Objective-C. Deck.m. Deck.h. Let s look at another class. This one represents a deck of cards. #import <Foundation/Foundation.h> #import "Deck.

COMPLETE TUTORIAL COURSE. Learn to make tvos LE. apps with real-worldam S F

CSE 303: Concepts and Tools for Software Development

Module 10A Lecture - 20 What is a function? Why use functions Example: power (base, n)

Mobile Application Programing: ios. Messaging

EXERCISES RELATED TO ios PROGRAMMING

Assignment I Walkthrough

Transcription:

Stanford Developing Applications for ios

Today Memory Management for Reference Types Controlling when things leave the heap Closure Capture Closures capture things into the heap too Extensions A simple, powerful, but easily overused code management syntax Protocols Last (but certainly not least important) typing mechanism in Swift Delegation An important use of protocols used throughout the ios frameworks API Scroll View Scrolling around in and zooming in on big things on a small screen

Memory Management Automatic Reference Counting Reference types (classes) are stored in the heap. How does the system know when to reclaim the memory for these from the heap? It counts references to each of them and when there are zero references, they get tossed. This is done automatically. It is known as Automatic Reference Counting and it is NOT garbage collection. Influencing ARC You can influence ARC by how you declare a reference-type var with these keywords strong weak unowned

strong Memory Management strong is normal reference counting As long as anyone, anywhere has a strong pointer to an instance, it will stay in the heap weak weak means if no one else is interested in this, then neither am I, set me to nil in that case Because it has to be nil-able, weak only applies to Optional pointers to reference types A weak pointer will NEVER keep an object in the heap Great example: outlets (strongly held by the view hierarchy, so outlets can be weak) unowned unowned means don t reference count this; crash if I m wrong This is very rarely used Usually only to break memory cycles between objects (more on that in a moment)

Closures Capturing Closures are stored in the heap as well (i.e. they are reference types). They can be put in Arrays, Dictionarys, etc. They are a first-class type in Swift. What is more, they capture variables they use from the surrounding code into the heap too. Those captured variables need to stay in the heap as long as the closure stays in the heap. This can create a memory cycle

Closures Example Imagine we added public API to allow a UnaryOperation to be added to the CalculatorBrain func addunaryoperation(symbol: String, operation: (Double) -> Double) This method would do nothing more than add a UnaryOperation to our Dictionary of enum Now let s imagine a View Controller was to add the operation red square root. This operation will do square root, but it will also turn the display red. addunaryoperation(!, operation: { (x: Double) -> Double in display.textcolor = UIColor.redColor() ) return sqrt(x)

Closures Example Imagine we added public API to allow a UnaryOperation to be added to the CalculatorBrain func addunaryoperation(symbol: String, operation: (Double) -> Double) This method would do nothing more than add a UnaryOperation to our Dictionary of enum Now let s imagine a View Controller was to add the operation red square root. This operation will do square root, but it will also turn the display red. addunaryoperation(!, operation: { (x: Double) -> Double in display.textcolor = UIColor.redColor() ) return sqrt(x)

Closures Example Imagine we added public API to allow a UnaryOperation to be added to the CalculatorBrain func addunaryoperation(symbol: String, operation: (Double) -> Double) This method would do nothing more than add a UnaryOperation to our Dictionary of enum Now let s imagine a View Controller was to add the operation red square root. This operation will do square root, but it will also turn the display red. addunaryoperation(! ) { (x: Double) -> Double in display.textcolor = UIColor.redColor() return sqrt(x)

Closures Example Imagine we added public API to allow a UnaryOperation to be added to the CalculatorBrain func addunaryoperation(symbol: String, operation: (Double) -> Double) This method would do nothing more than add a UnaryOperation to our Dictionary of enum Now let s imagine a View Controller was to add the operation red square root. This operation will do square root, but it will also turn the display red. addunaryoperation(! ) { (x: Double) -> Double in display.textcolor = UIColor.redColor() return sqrt(x)

Closures Example Imagine we added public API to allow a UnaryOperation to be added to the CalculatorBrain func addunaryoperation(symbol: String, operation: (Double) -> Double) This method would do nothing more than add a UnaryOperation to our Dictionary of enum Now let s imagine a View Controller was to add the operation red square root. This operation will do square root, but it will also turn the display red. addunaryoperation(! ) { display.textcolor = UIColor.redColor() return sqrt($0) But this will not compile.

Closures Example Imagine we added public API to allow a UnaryOperation to be added to the CalculatorBrain func addunaryoperation(symbol: String, operation: (Double) -> Double) This method would do nothing more than add a UnaryOperation to our Dictionary of enum Now let s imagine a View Controller was to add the operation red square root. This operation will do square root, but it will also turn the display red. addunaryoperation(! ) { self.display.textcolor = UIColor.redColor() return sqrt($0) Swift forces you to put self. here to remind you that self will get captured! The Model and the Controller now point to each other through the closure. And thus neither can ever leave the heap. This is called a memory cycle.

Closures So how do we break this cycle? Swift lets you control this capture behavior addunaryoperation(! ) { [ <special variable declarations> ] in self.display.textcolor = UIColor.redColor() return sqrt($0)

Closures So how do we break this cycle? Swift lets you control this capture behavior addunaryoperation(! ) { [ me = self ] in me.display.textcolor = UIColor.redColor() return sqrt($0)

Closures So how do we break this cycle? Swift lets you control this capture behavior addunaryoperation(! ) { [ unowned me = self ] in me.display.textcolor = UIColor.redColor() return sqrt($0)

Closures So how do we break this cycle? Swift lets you control this capture behavior addunaryoperation(! ) { [ unowned self = self ] in self.display.textcolor = UIColor.redColor() return sqrt($0)

Closures So how do we break this cycle? Swift lets you control this capture behavior addunaryoperation(! ) { [ unowned self ] in self.display.textcolor = UIColor.redColor() return sqrt($0)

Closures So how do we break this cycle? Swift lets you control this capture behavior addunaryoperation(! ) { [ weak self ] in self.display.textcolor = UIColor.redColor() return sqrt($0)

Closures So how do we break this cycle? Swift lets you control this capture behavior addunaryoperation(! ) { [ weak self ] in self?.display.textcolor = UIColor.redColor() return sqrt($0)

Closures So how do we break this cycle? Swift lets you control this capture behavior addunaryoperation(! ) { [ weak weakself = self weakself?.display.textcolor = UIColor.redColor() return sqrt($0) ] in

Demo Red Square Root Let s do what we just talked about and see it in action in our Calculator

Extensions Extending existing data structures You can add methods/properties to a class/struct/enum (even if you don t have the source). For example, this adds a method contentviewcontroller to UIViewController extension UIViewController { var contentviewcontroller: UIViewController { if let navcon = self as? UINavigationController { return navcon.visibleviewcontroller else { return self it can be used to clean up prepareforsegue code var destination: UIViewController? = segue.destinationviewcontroller if let navcon = destination as? UINavigationController { destination = navcon.visibleviewcontroller if let myvc = destination as? MyVC {

Extensions Extending existing data structures You can add methods/properties to a class/struct/enum (even if you don t have the source). For example, this adds a method contentviewcontroller to UIViewController extension UIViewController { var contentviewcontroller: UIViewController { if let navcon = self as? UINavigationController { return navcon.visibleviewcontroller else { return self it can be used to clean up prepareforsegue code if let myvc = segue.destinationviewcontroller.contentviewcontroller as? MyVC {

Extensions Extending existing data structures You can add methods/properties to a class/struct/enum (even if you don t have the source). For example, this adds a method contentviewcontroller to UIViewController extension UIViewController { var contentviewcontroller: UIViewController { if let navcon = self as? UINavigationController { return navcon.visibleviewcontroller else { return self Notice that when it refers to self, it means the thing it is extending (UIViewController).

Extensions Extending existing data structures You can add methods/properties to a class/struct/enum (even if you don t have the source). There are some restrictions You can t re-implement methods or properties that are already there (only add new ones). The properties you add can have no storage associated with them (computed only). This feature is easily abused It should be used to add clarity to readability not obfuscation! Don t use it as a substitute for good object-oriented design technique. Best used (at least for beginners) for very small, well-contained helper functions. Can actually be used well to organize code but requires architectural commitment. When in doubt (for now), don t do it.

Protocols Protocols are a way to express an API more concisely Instead of forcing the caller of an API to pass a specific class, struct, or enum, an API can let callers pass any class/struct/enum that the caller wants but can require that they implement certain methods and/or properties that the API wants. To specify which methods and properties the API wants, the API is expressed using a Protocol. A Protocol is simply a collection of method and property declarations. A Protocol is a TYPE It can be used almost anywhere any other type is used: vars, function parameters, etc. The implementation of a Protocol s methods and properties The implementation is provided by an implementing type (any class, struct or enum). Because of this, a protocol can have no storage associated with it (any storage required to implement the protocol is provided by an implementing type). It is possible to add implementation to a protocol via an extension to that protocol (but remember that extensions also cannot use any storage)

Protocols There are four aspects to a protocol 1. the protocol declaration (what properties and methods are in the protocol) 2. the declaration where a class, struct or enum claims that it implements a protocol 3. the code that implements the protocol in said class, struct or enum 4. optionally, an extension to the protocol which provides some default implementation Optional methods in a protocol Normally any protocol implementor must implement all the methods/properties in the protocol. However, it is possible to mark some methods in a protocol optional (don t get confused with the type Optional, this is a different thing). Any protocol that has optional methods must be marked @objc. And any optional-protocol implementing class must inherit from NSObject. Used often in ios for delegation (more later on this). Except for delegation, a protocol with optional methods is rarely (if ever) used. As you can tell from the @objc designation, it s mostly for backwards compatibility.

Protocols Declaration of the protocol itself protocol SomeProtocol : InheritedProtocol1, InheritedProtocol2 { var someproperty: Int { get set func amethod(arg1: Double, anotherargument: String) -> SomeType mutating func changeit() init(arg: Type)

Protocols Declaration of the protocol itself protocol SomeProtocol : InheritedProtocol1, InheritedProtocol2 { var someproperty: Int { get set func amethod(arg1: Double, anotherargument: String) -> SomeType mutating func changeit() init(arg: Type) Anyone that implements SomeProtocol must also implement InheritedProtocol1 and 2

Protocols Declaration of the protocol itself protocol SomeProtocol : InheritedProtocol1, InheritedProtocol2 { var someproperty: Int { get set func amethod(arg1: Double, anotherargument: String) -> SomeType mutating func changeit() init(arg: Type) Anyone that implements SomeProtocol must also implement InheritedProtocol1 and 2 You must specify whether a property is get only or both get and set

Protocols Declaration of the protocol itself protocol SomeProtocol : InheritedProtocol1, InheritedProtocol2 { var someproperty: Int { get set func amethod(arg1: Double, anotherargument: String) -> SomeType mutating func changeit() init(arg: Type) Anyone that implements SomeProtocol must also implement InheritedProtocol1 and 2 You must specify whether a property is get only or both get and set Any functions that are expected to mutate the receiver should be marked mutating

Protocols Declaration of the protocol itself protocol SomeProtocol : class, InheritedProtocol1, InheritedProtocol2 { var someproperty: Int { get set func amethod(arg1: Double, anotherargument: String) -> SomeType mutating func changeit() init(arg: Type) Anyone that implements SomeProtocol must also implement InheritedProtocol1 and 2 You must specify whether a property is get only or both get and set Any functions that are expected to mutate the receiver should be marked mutating (unless you are going to restrict your protocol to class implementers only with class keyword)

Protocols Declaration of the protocol itself protocol SomeProtocol : InheritedProtocol1, InheritedProtocol2 { var someproperty: Int { get set func amethod(arg1: Double, anotherargument: String) -> SomeType mutating func changeit() init(arg: Type) Anyone that implements SomeProtocol must also implement InheritedProtocol1 and 2 You must specify whether a property is get only or both get and set Any functions that are expected to mutate the receiver should be marked mutating (unless you are going to restrict your protocol to class implementers only with class keyword) You can even specify that implementers must implement a given initializer

How an implementer says I implement that protocol class SomeClass : SuperclassOfSomeClass, SomeProtocol, AnotherProtocol { // implementation of SomeClass here // w hich must include all the properties and methods in SomeProtocol & AnotherProtocol Protocols Claims of conformance to protocols are listed after the superclass for a class

Protocols How an implementer says I implement that protocol enum SomeEnum : SomeProtocol, AnotherProtocol { // implementation of SomeEnum here // w hich must include all the properties and methods in SomeProtocol & AnotherProtocol Claims of conformance to protocols are listed after the superclass for a class Obviously, enums and structs would not have the superclass part

Protocols How an implementer says I implement that protocol struct SomeStruct : SomeProtocol, AnotherProtocol { // implementation of SomeStruct here // w hich must include all the properties and methods in SomeProtocol & AnotherProtocol Claims of conformance to protocols are listed after the superclass for a class Obviously, enums and structs would not have the superclass part

Protocols How an implementer says I implement that protocol struct SomeStruct : SomeProtocol, AnotherProtocol { // implementation of SomeStruct here // w hich must include all the properties and methods in SomeProtocol & AnotherProtocol Claims of conformance to protocols are listed after the superclass for a class Obviously, enums and structs would not have the superclass part Any number of protocols can be implemented by a given class, struct or enum

How an implementer says I implement that protocol class SomeClass : SuperclassOfSomeClass, SomeProtocol, AnotherProtocol { // implementation of SomeClass here, including required init( ) Protocols Claims of conformance to protocols are listed after the superclass for a class Obviously, enums and structs would not have the superclass part Any number of protocols can be implemented by a given class, struct or enum In a class, inits must be marked required (or otherwise a subclass might not conform)

How an implementer says I implement that protocol extension Something : SomeProtocol { // implementation of SomeProtocol here // no stored properties though Protocols Claims of conformance to protocols are listed after the superclass for a class Obviously, enums and structs would not have the superclass part Any number of protocols can be implemented by a given class, struct or enum In a class, inits must be marked required (or otherwise a subclass might not conform) You are allowed to add protocol conformance via an extension

Protocols Using protocols like the type that they are! protocol Moveable { mutating func moveto(p: CGPoint) class Car : Moveable { func moveto(p: CGPoint) { func changeoil() struct Shape : Moveable { mutating func moveto(p: CGPoint) { func draw() let prius: Car = Car() let square: Shape = Shape()

Protocols Using protocols like the type that they are! protocol Moveable { mutating func moveto(p: CGPoint) class Car : Moveable { func moveto(p: CGPoint) { func changeoil() struct Shape : Moveable { mutating func moveto(p: CGPoint) { func draw() let prius: Car = Car() let square: Shape = Shape()

Protocols Using protocols like the type that they are! protocol Moveable { mutating func moveto(p: CGPoint) class Car : Moveable { func moveto(p: CGPoint) { func changeoil() struct Shape : Moveable { mutating func moveto(p: CGPoint) { func draw() let prius: Car = Car() let square: Shape = Shape() var thingtomove: Moveable = prius thingtomove.moveto( ) thingtomove.changeoil() thingtomove = square let thingstomove: [Moveable] = [prius, square] func slide(slider: Moveable) { let positiontoslideto = slider.moveto(positiontoslideto) slide(prius) slide(square) func slipandslide(x: protocol<slippery,moveable>) slipandslide(prius)

Delegation A very important use of protocols It s a way to implement blind communication between a View and its Controller should will did Controller data at count delegate data source View

Delegation A very important use of protocols It s a way to implement blind communication between a View and its Controller How it plays out 1. A View declares a delegation protocol (i.e. what the View wants the Controller to do for it) 2. The View s API has a weak delegate property whose type is that delegation protocol 3. The View uses the delegate property to get/do things it can t own or control on its own 4. The Controller declares that it implements the protocol 5. The Controller sets self as the delegate of the View by setting the property in #2 above 6. The Controller implements the protocol (probably it has lots of optional methods in it) Now the View is hooked up to the Controller But the View still has no idea what the Controller is, so the View remains generic/reusable This mechanism is found throughout ios However, it was designed pre-closures in Swift. Closures are often a better option.

Example Delegation UIScrollView (which we ll talk about in a moment) has a delegate property weak var delegate: UIScrollViewDelegate? The UIScrollViewDelegate protocol looks like this @objc protocol UIScrollViewDelegate { optional func scrollviewdidscroll(scrollview: UIScrollView) optional func viewforzoominginscrollview(scrollview: UIScrollView) -> UIView and many more A Controller with a UIScrollView in its View would be declared like this class MyViewController : UIViewController, UIScrollViewDelegate { and in its viewdidload() or in the scroll view outlet setter, it would do scrollview.delegate = self and it then would implement any of the protocol s methods it is interested in.

UIScrollView

Adding subviews to a normal UIView... logo.frame = CGRect(x: 300, y: 50, width: 120, height: 180) view.addsubview(logo)

Adding subviews to a UIScrollView... scrollview.contentsize = CGSize(width: 3000, height: 2000) logo.frame = CGRect(x: 2700, y: 50, width: 120, height: 180) scrollview.addsubview(logo)

Adding subviews to a UIScrollView... scrollview.contentsize = CGSize(width: 3000, height: 2000) aerial.frame = CGRect(x: 150, y: 200, width: 2500, height: 1600) scrollview.addsubview(aerial)

Adding subviews to a UIScrollView... scrollview.contentsize = CGSize(width: 3000, height: 2000) aerial.frame = CGRect(x: 150, y: 200, width: 2500, height: 1600) scrollview.addsubview(aerial)

Scrolling in a UIScrollView...

Scrolling in a UIScrollView...

Scrolling in a UIScrollView...

Scrolling in a UIScrollView...

Positioning subviews in a UIScrollView... aerial.frame = CGRect(x: 0, y: 0, width: 2500, height: 1600)

Positioning subviews in a UIScrollView... aerial.frame = CGRect(x: 0, y: 0, width: 2500, height: 1600) logo.frame = CGRect(x: 2300, y: 50, width: 120, height: 180)

Positioning subviews in a UIScrollView... aerial.frame = CGRect(x: 0, y: 0, width: 2500, height: 1600) logo.frame = CGRect(x: 2300, y: 50, width: 120, height: 180) scrollview.contentsize = CGSize(width: 2500, height: 1600)

That s it!

That s it!

That s it!

That s it!

That s it!

Where in the content is the scroll view currently positioned? let upperleftofvisible: CGPoint = scrollview.contentoffset In the content area s coordinate system. contentoffset.y contentoffset.x

What area in a subview is currently visible? let visiblerect: CGRect = aerial.convertrect(scrollview.bounds, fromview: scrollview) Why the convertrect? Because the scrollview s bounds are in the scrollview s coordinate system. And there might be zooming going on inside the scrollview too

UIScrollView How do you create one? Just like any other UIView. Drag out in a storyboard or use UIScrollView(frame:). Or select a UIView in your storyboard and choose Embed In -> Scroll View from Editor menu. To add your too big UIView in code using addsubview let image = UIImage(named: bigimage.jpg ) let iv = UIImageView(image: image) // iv.frame.size will = image.size scrollview.addsubview(iv) Add more subviews if you want. All of the subviews frames will be in the UIScrollView s content area s coordinate system (that is, (0,0) in the upper left & width and height of contentsize.width &.height). Now don t forget to set the contentsize Common bug is to do the above 3 lines of code (or embed in Xcode) and forget to say: scrollview.contentsize = imageview.bounds.size (for example)

Scrolling programmatically UIScrollView func scrollrecttovisible(cgrect, animated: Bool) Other things you can control in a scroll view Whether scrolling is enabled. Locking scroll direction to user s first move. The style of the scroll indicators (call flashscrollindicators when your scroll view appears). Whether the actual content is inset from the content area (contentinset property).

UIScrollView Zooming All UIView s have a property (transform) which is an affine transform (translate, scale, rotate). Scroll view simply modifies this transform when you zoom. Zooming is also going to affect the scroll view s contentsize and contentoffset. Will not work without minimum/maximum zoom scale being set scrollview.minimumzoomscale = 0.5 scrollview.maximumzoomscale = 2.0 // 0.5 means half its normal size // 2.0 means twice its normal size Will not work without delegate method to specify view to zoom func viewforzoominginscrollview(sender: UIScrollView) -> UIView If your scroll view only has one subview, you return it here. More than one? Up to you. Zooming programatically var zoomscale: CGFloat func setzoomscale(cgfloat, animated: Bool) func zoomtorect(cgrect, animated: Bool)

scrollview.zoomscale = 1.2

scrollview.zoomscale = 1.0

scrollview.zoomscale = 1.2

zoomtorect(cgrect, animated: Bool)

zoomtorect(cgrect, animated: Bool)

zoomtorect(cgrect, animated: Bool)

zoomtorect(cgrect, animated: Bool)

UIScrollView Lots and lots of delegate methods! The scroll view will keep you up to date with what s going on. Example: delegate method will notify you when zooming ends func scrollviewdidendzooming(uiscrollview, withview: UIView, // from delegate method above atscale: CGFloat) If you redraw your view at the new scale, be sure to reset the transform back to identity.