Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

70
Standford 2015 iOS讀書會 week4 1. Protocols and Delegation, Gestures 2. Multiple MVCs 彼得潘

Transcript of Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

Page 1: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

Standford 2015 iOS讀書會 week4

1. Protocols and Delegation, Gestures 2. Multiple MVCs

彼得潘

Page 2: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

Protocols and Delegation, Gestures

Page 3: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

@IBDesignable 在storyboard顯⽰示客製化的UI元件

@IBDesignable class FaceView: UIView {

Page 4: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

@IBInspectable @IBInspectable var scale:CGFloat = 0.9 { didSet { setNeedsDisplay() } } @IBInspectable var lineWidth:CGFloat = 3 { didSet { setNeedsDisplay() } } @IBInspectable var color:UIColor = UIColor.blueColor() { didSet { setNeedsDisplay() } }

在storyboard增加元件的設定欄位⽀支援的欄位型別:

booleans, strings, numbers CGPoint, CGSize, CGRect, UIColor, NSRange, UIImage

Page 5: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

var happiness:Int = 50 { didSet { happiness = min(max(happiness, 0), 100) updateUI() } }

在property observer裡修改property, 不會觸發observer再次被呼叫

Page 6: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

升級原有型別能⼒力的extension

• computed property。(不⽀支援stored property) • ⽅方法 • initializer • subscript • 遵從protocol,定義protocol裡宣告的⽅方法屬性 • nested type

Page 7: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

升級原有型別能⼒力的extension

Page 8: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

出⼀一張嘴,只宣告不定義的protocol可宣告⽅方法,computed property,

subscript,initializer

get⼀一定要有,set可有可無

class, struct , enum可實作protocol

Page 9: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

出⼀一張嘴,只宣告不定義的protocol

Page 10: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

出⼀一張嘴,只宣告不定義的protocol

要⽤用 as!

Page 11: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

宣告遵從多個protocol的變數

protocol Idol { func sing() }

protocol Artist { func paint() }

var man:Idol! var woman:protocol<Idol, Artist>!

Page 12: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

不⼀一定要定義的optional

要加上@objc 和import Foundation

import Foundation

@objc protocol Idol { func sing() func run() optional var money:Double { get } optional func playPiano() -> String }

Page 13: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

不⼀一定要定義的optional

加了optional的protocol只有class可以遵從

此時class也要加上@objc

@objc class Baby:Idol { func sing() { } func run() { } func playPiano() -> String { return "hi" } }

var cuteBaby:Idol = Baby() cuteBaby.playPiano?()

Page 14: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

protocol

Page 15: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

protocol

實作protocol的init要加上required (因為subclass可能沒有繼承init)

Page 16: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Page 17: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Page 18: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

demoprotocol FaceViewDataSource:class { func smilinessForFaceView(sender:FaceView) -> Double? }

delegate的⽅方法常常會將⾃自⼰己當參數代理⼈人可依此做不同的處理

ex: smilinessForFaceView的sender

weak var dataSource:FaceViewDataSource?

weak只能作⽤用於物件,所以要加class

let smiliness = self.dataSource?.smilinessForFaceView(self) ?? 0 let smilePath = bezierPathForSmile(smiliness)

Page 19: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

遇nil即臨陣脫逃的 optional chaining

optional chaining的回傳結果也會是optional

Page 20: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

遇nil即臨陣脫逃的optional chaining

利用optional binding判斷可能為nil的cuteBaby和eatFood

定義Food類別和Baby類別

Page 21: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

遇nil即臨陣脫逃的optional chaining

利用optional chaining在function eat回傳的Food存取name

利用optional chaining在optional的cuteBaby上呼叫eat function

Page 22: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

遇nil即臨陣脫逃的optional chaining

透過optional chaining存取的age也會是optional,不能直接做加法運算

Page 23: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

遇nil即臨陣脫逃的optional chainingdog1當初宣告時不是optional,不用加?存取下一層的food

dog1並非宣告為optional,此生注定和!無緣

Page 24: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

變出預設值的雙重問號 當age等於nil時,一律回覆18歲

當age為nil時,回傳雙重問號右邊的預設值18

Page 25: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

demo

func smilinessForFaceView(sender: FaceView) -> Double? { return Double(self.happiness - 50)/50 }

class HappinessViewController: UIViewController, FaceViewDataSource {

@IBOutlet weak var faceView: FaceView! { didSet { self.faceView.dataSource = self } }

當faceView連結設定時,設定dataSource為self

func updateUI() { faceView.setNeedsDisplay() }

Page 26: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

cmd + shift + o

開啟open quickly視窗

Page 27: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

gestureUITapGestureRecognizer

UISwipeGestureRecognizer

UIPanGestureRecognizer

UIPinchGestureRecognizer

UIRotationGestureRecognizer

UILongPressGestureRecognizer

UIScreenEdgePanGestureRecognizer類似UIPanGestureRecognizer,但限制⼿手勢須從螢幕邊緣開始

Page 28: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

使⽤用gesture

1.加gesture加到作⽤用的view上

2.設定gesture發⽣生時觸發的method

Page 29: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

gesture觸發的⽅方法

Page 30: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

gesture觸發的⽅方法實例

Page 31: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

不同gesture包含 不同的資訊

Page 32: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

demo func pan(gesture:UIPanGestureRecognizer) { switch gesture.state { case .Changed: fallthrough case .Ended: let translation = gesture.translationInView(blueView) println("translation \(translation)") gesture.setTranslation(CGPointZero, inView:blueView) default: break } }

觀察呼叫gesture.setTranslation和沒有呼叫gesture.setTranslation的差別

Page 33: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

利⽤用pan移動view:⽅方法1

func pan(gesture:UIPanGestureRecognizer) { switch gesture.state { case .Began: originalCenter = blueView.center case .Changed: fallthrough case .Ended: let translation = gesture.translationInView(blueView) blueView.center = CGPointMake(originalCenter.x + translation.x, originalCenter.y + translation.y); default: break } }

class ViewController: UIViewController { var originalCenter:CGPoint!

Page 34: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

利⽤用pan移動view:⽅方法2func pan(gesture:UIPanGestureRecognizer) { switch gesture.state { case .Changed: fallthrough case .Ended: let translation = gesture.translationInView(blueView) let originalCenter = blueView.center blueView.center = CGPointMake(originalCenter.x + translation.x, originalCenter.y + translation.y); gesture.setTranslation(CGPointZero, inView:blueView) default: break } }

Page 35: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

pan gesture

var minimumNumberOfTouches: Int // default is 1. the minimum number of touches required to match

var maximumNumberOfTouches: Int // default is UINT_MAX. the maximum number of touches that can be down

Page 36: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

standford demo

func scale(gesture:UIPinchGestureRecognizer) { scale = scale * gesture.scale gesture.scale = 1 }

@IBOutlet weak var faceView: FaceView! { didSet { self.faceView.dataSource = self self.faceView.addGestureRecognizer(UIPinchGestureRecognizer(target: self.faceView, action: "scale:")) } }

Page 37: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

從storyboard加gesture

Page 38: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

從storyboard加gesture private struct Constants { static let HappinessGestureScale:CGFloat = 4 } @IBAction func changeHappiness(sender: UIPanGestureRecognizer) { switch sender.state { case .Ended: fallthrough case .Changed: let translation = sender.translationInView(faceView) let happinessChange = -Int(translation.y / Constants.HappinessGestureScale) if happinessChange != 0 { happiness += happinessChange sender.setTranslation(CGPointZero, inView: faceView) } default: break } }

⼿手指往下 -> 不開⼼心⼿手指往上 -> 開⼼心

Page 39: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

模擬器pinch

按住option後,按觸控版移動

https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/iOS_Simulator_Guide/

InteractingwiththeiOSSimulator.html

Page 40: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

Multiple MVCs

Page 41: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

第五個tab: more

Page 42: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

For iPadiPhone只有6 plus的landscape會分割畫⾯面iPhone模式下的問題

Page 43: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

UITabBarController & UINavigationController的結合

Page 44: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Page 45: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Page 46: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

Show: 1.有navigation controller⽤用push2. 沒有navigation controller⽤用modal

Show Detail: 1.有Split View Controller顯⽰示detail(Split View Controller若搭配navigation controller,

在iPhone會採⽤用push顯⽰示detail,除了6 plus landscape例外) 2. 沒有Split View Controller⽤用modal

Page 47: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

func performSegueWithIdentifier(identifier: String, sender: AnyObject?)

從程式觸發切換到另⼀一個controller畫⾯面

Page 48: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

Once the MVC is prepared, it should run on its own power (only using delegation to talk back)

It is crucial to understand that this preparation is happening BEFORE outlets get set!!

Page 49: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

防⽌止segue發⽣生

func shouldPerformSegueWithIdentifier(identifier: String?, sender: AnyObject?) -> Bool

Page 50: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

⽐比較Reset to Suggested Constraints & Add Missing Constraints

Page 51: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

⾃自動縮放字型⼤大⼩小

Page 52: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

Split View Controller的iPhone 問題

Page 53: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

解法: master加上navigation controller

Page 54: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

func updateUI() { faceView.setNeedsDisplay() }

func updateUI() { faceView?.setNeedsDisplay() }

修正nil crash問題

optional chaining

Page 55: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

笑臉被bar檔到了

Page 56: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

修正笑臉檔到問題

Page 57: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

iPad版笑臉加標題

Page 58: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

iPad版笑臉加標題

Page 59: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Page 60: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

property observer的override保留⽗父類別的observer

Page 61: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

property observer的override保留⽗父類別的observer

Page 62: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

property observer的override

Page 63: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

問題: history只有⼀一筆資料

因為DiagnosedHappinessViewController會重新⽣生成

Page 64: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

問題: history只有⼀一筆資料

利⽤用user defaults儲存

private let defaults = NSUserDefaults.standardUserDefaults() var diagnosticHisotry:[Int] { get { return defaults.objectForKey(History.DefaultsKey) as? [Int] ?? [] } set { defaults.setObject(newValue, forKey: History.DefaultsKey) } }

Page 65: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

修正iPhone Popover 全螢幕的問題

Page 66: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

修正iPhone Popover 全螢幕的問題

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle { return UIModalPresentationStyle.None }

class DiagnosedHappinessViewController : HappinessViewController, UIPopoverPresentationControllerDelegate

實作UIPopoverPresentationControllerDelegate的⽅方法

Page 67: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if let identifier = segue.identifier { switch identifier { case History.SegueIdentifier: if let tvc = segue.destinationViewController as? TextViewController { if let ppc = tvc.popoverPresentationController { ppc.delegate = self } tvc.text = "\(diagnosticHisotry)" } default: break } } }

修正iPhone Popover 全螢幕的問題

Page 68: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

修正iPhone Popover 全螢幕的問題

Page 69: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

調整pop over的size

override var preferredContentSize:CGSize { get { if textView != nil && presentingViewController != nil { let size = textView.sizeThatFits(presentingViewController!.view.bounds.size) println("size \(size)") return textView.sizeThatFits(presentingViewController!.view.bounds.size) } else { return super.preferredContentSize } } set { super.preferredContentSize = newValue } }

定義UIViewController的preferredContentSize property

Page 70: Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs

調整pop over的size