Top Banner
Standford 2015 iOS讀書會 week6 1. Multithreading 2. Table View 彼得潘
65

Standford 2015 week6

Jul 28, 2015

Download

Mobile

胖哥哥 Pan
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Standford 2015 week6

Standford 2015 iOS讀書會 week6

1. Multithreading 2. Table View

彼得潘

Page 2: Standford 2015 week6

Main Queue: serial queue,⼀一次從queue取出⼀一個function執⾏行

UI相關動作⼀一定要在main queue執⾏行

Grand Central Dispatch

Page 3: Standford 2015 week6
Page 4: Standford 2015 week6

dispatch_async & dispatch_sync

async: return after task is added to queue

sync: return after task is done

Page 5: Standford 2015 week6
Page 6: Standford 2015 week6

serial & concurrent queue

https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

Page 7: Standford 2015 week6

demo var number1 = 0 var number2 = 0 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let queue = dispatch_queue_create("Queue", DISPATCH_QUEUE_SERIAL) dispatch_async(queue, { () -> Void in for i in 1...10 { self.number1++ NSThread.sleepForTimeInterval(0.1) if i == 10 { println("number1 \(self.number1) number2 \(self.number2)")

} } }) println("dispatch_async1") dispatch_async(queue, { () -> Void in for i in 1...10 { self.number2++ } }) println("dispatch_async2")

}

dispatch_async1 dispatch_async2 number1 10 number2 0

serial: FIFO

Page 8: Standford 2015 week6

demo var number1 = 0 var number2 = 0 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let queue = dispatch_queue_create("Queue", DISPATCH_QUEUE_CONCURRENT) dispatch_async(queue, { () -> Void in for i in 1...10 { self.number1++ NSThread.sleepForTimeInterval(0.1) if i == 10 { println("number1 \(self.number1) number2 \(self.number2)")

} } }) println("dispatch_async1") dispatch_async(queue, { () -> Void in for i in 1...10 { self.number2++ } }) println("dispatch_async2")

}

dispatch_async1 dispatch_async2 number1 10 number2 10

Page 9: Standford 2015 week6

demo var number1 = 0 var number2 = 0 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let queue = dispatch_queue_create("Queue", DISPATCH_QUEUE_SERIAL) dispatch_sync(queue, { () -> Void in for i in 1...10 { self.number1++ NSThread.sleepForTimeInterval(0.1) if i == 10 { println("number1 \(self.number1) number2 \(self.number2)")

} } }) println("dispatch_sync1") dispatch_sync(queue, { () -> Void in for i in 1...10 { self.number2++ } }) println("dispatch_sync2")

}

number1 10 number2 0dispatch_sync1dispatch_sync2

Page 10: Standford 2015 week6

demo var number1 = 0 var number2 = 0 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let queue = dispatch_queue_create("Queue", DISPATCH_QUEUE_CONCURRENT) dispatch_sync(queue, { () -> Void in for i in 1...10 { self.number1++ NSThread.sleepForTimeInterval(0.1) if i == 10 { println("number1 \(self.number1) number2 \(self.number2)")

} } }) println("dispatch_sync1") dispatch_sync(queue, { () -> Void in for i in 1...10 { self.number2++ } }) println("dispatch_sync2")

}

number1 10 number2 0dispatch_sync1dispatch_sync2

Page 11: Standford 2015 week6
Page 12: Standford 2015 week6

不在main thread做UI會 ->

Crash ,變慢,奇怪現象

Page 13: Standford 2015 week6

NSURLSessionfunc testDownload() { let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration()) if let url = NSURL(string: "http://res.cloudinary.com/hrscywv4p/image/upload/c_limit,f_auto,h_3000,q_80,w_1200/v1/271374/http_s3.amazonaws.com_feather-files-aviary-prod-us-east-1_f5da8ea5e_2015-03-12_723490bbf79e44a788f5cd2516fefd46_myvzle.jpg") { let request = NSURLRequest(URL: url) let task = session.downloadTaskWithRequest(request, completionHandler: { (localUrl, response, err) -> Void in let data = NSData(contentsOfURL: localUrl) let image = UIImage(data: data!) let imageView = UIImageView(image: image) self.view.addSubview(imageView) println("add image")

}) task.resume() } } 圖⽚片過⼀一段時間才出現

Page 14: Standford 2015 week6

NSURLSession func testDownload() { let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration()) if let url = NSURL(string: "http://res.cloudinary.com/hrscywv4p/image/upload/c_limit,f_auto,h_3000,q_80,w_1200/v1/271374/http_s3.amazonaws.com_feather-files-aviary-prod-us-east-1_f5da8ea5e_2015-03-12_723490bbf79e44a788f5cd2516fefd46_myvzle.jpg") { let request = NSURLRequest(URL: url) let task = session.downloadTaskWithRequest(request, completionHandler: { (localUrl, response, err) -> Void in let data = NSData(contentsOfURL: localUrl) let image = UIImage(data: data!) dispatch_async(dispatch_get_main_queue(), { () -> Void in let imageView = UIImageView(image: image) self.view.addSubview(imageView)

}) }) task.resume() } }

Page 15: Standford 2015 week6

建⽴立session

let session = NSURLSession.sharedSession()

let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())

預設會將抓到的資料存在disk,App重新啟動還會存在

若是抓取size太⼤大的資料不會儲存在disk

Page 16: Standford 2015 week6

建⽴立task

let task = session.dataTaskWithURL(url, completionHandler: { (data, response, err) -> Void in let image = UIImage(data: data!) dispatch_async(dispatch_get_main_queue(), { () -> Void in let imageView = UIImageView(image: image) self.view.addSubview(imageView) }) })

let task = session.downloadTaskWithRequest(request, completionHandler: { (localUrl, response, err) -> Void in let data = NSData(contentsOfURL: localUrl) let image = UIImage(data: data!) dispatch_async(dispatch_get_main_queue(), { () -> Void in let imageView = UIImageView(image: image) self.view.addSubview(imageView)

}) })

Page 17: Standford 2015 week6

private func fetchImage() { if let url = imageURL { spinner?.startAnimating() let qos = Int(QOS_CLASS_USER_INITIATED.value) dispatch_async(dispatch_get_global_queue(qos, 0)) { () -> Void in let imageData = NSData(contentsOfURL: url) // this blocks the thread it is on dispatch_async(dispatch_get_main_queue()) { // only do something with this image // if the url we fetched is the current imageURL we want // (that might have changed while we were off fetching this one) if url == self.imageURL { // the variable "url" is capture from above if imageData != nil { // this might be a waste of time if our MVC is out of action now // which it might be if someone hit the Back button // or otherwise removed us from split view or navigation controller // while we were off fetching the image self.image = UIImage(data: imageData!) } else { self.image = nil } } } } } }

closure裡要⽤用self.image,不能只⽤用imageif url == self.imageURL : 判斷是否是⺫⽬目前要顯⽰示的圖⽚片

⽤用weak , unowned 設定self ?

Page 18: Standford 2015 week6

table

Page 19: Standford 2015 week6

⼀一⾏行,多⾏行輸⼊入需⽤用UITextView

Page 20: Standford 2015 week6

收鍵盤⽅方法⼤大全

1. 在畫⾯面上加⼊入tap gesture 2. 設定return鍵觸發,經由設定Did End On Exit Event或是

delete的textFieldShouldReturn

⽅方法⼀一: resignFirstResponder ⽅方法⼆二: self.view.endEditing(true) ⽅方法三: 設定keyboardDismissMode

觸發⽅方法:

Page 21: Standford 2015 week6
Page 22: Standford 2015 week6

autocapitalizationType: 控制⼤大⼩小寫

Page 23: Standford 2015 week6

observer死掉時,會⾃自動被NSNotificationCenter移除

UITableViewController搭配UITextView和UITextField獲得⾃自動scroll魔⼒力

addObserver不會增加observer的retina count

Page 24: Standford 2015 week6

inputView: 客製化鍵盤,⽐比⽅方將picker設成鍵盤

Page 25: Standford 2015 week6
Page 26: Standford 2015 week6
Page 27: Standford 2015 week6

UITableViewDataSource’s tableView(UITableView, cellForRowAtIndexPath: NSIndexPath)

UITableViewDataSource’s tableView(UITableView, titleForFooterInSection: Int)

UITableViewDataSource’s tableView(UITableView, titleForHeaderInSection: Int)

var tableFooterView: UIView

var tableHeaderView: UIView

Page 28: Standford 2015 week6
Page 29: Standford 2015 week6

section: 滑動表格時會固定在畫⾯面上⽅方,參考通訊錄App

Page 30: Standford 2015 week6
Page 31: Standford 2015 week6

UITableViewController

view就是tableView

⾃自動連結data source & delegate

如果⾃自⼰己拉的table view要⼿手動連結

static⼀一定要搭配UITableViewController

keyboard auto scroll

Page 32: Standford 2015 week6

不限數量的內容

Page 33: Standford 2015 week6

Dynamic Prototypes

Page 34: Standford 2015 week6

內容⾏行數固定的表格百分之五⼗十的畫⾯面是⾏行數固定的Table

Page 35: Standford 2015 week6

Static Cells只能搭配UITableViewController!

Page 36: Standford 2015 week6

多出來的分隔線?

Page 37: Standford 2015 week6

清除多出來的分隔線: tableFooterView

tableFooterViewtableHeaderView

加了header才能加footer

Page 38: Standford 2015 week6

超級⽐比⼀一⽐比@property (nonatomic, retain) UIView *tableHeaderView;

@property (nonatomic, retain) UIView *tableFooterView;

- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);

- (UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;

Page 39: Standford 2015 week6

⽅方法⼀一: UITableViewController做child controller

讓整個畫⾯面只有某部分是table的⽅方法

⽅方法⼆二: UITableView做subview

Page 40: Standford 2015 week6
Page 41: Standford 2015 week6

cell reuse: 圖⽚片download問題

圖⽚片完成下載時,cell已被reuse解法: : ⽅方法⼀一:在cell裡儲存url,⽐比對url確認是否顯⽰示 ⽅方法⼆二:定義cell的prepareForReuse,於其中終⽌止下載圖⽚片的動作

Page 42: Standford 2015 week6
Page 43: Standford 2015 week6
Page 44: Standford 2015 week6

cell裡設定IBOutlet & IBAction

IBOutlet連結到cell的程式檔

IBAction連結到controller的程式檔

IBOutlet不能連結到controller的程式檔

Page 45: Standford 2015 week6

在storyboard從cell拉segue時, 可以選selection 或 accessory action (對應Detail Disclosure)

Page 46: Standford 2015 week6
Page 47: Standford 2015 week6
Page 48: Standford 2015 week6
Page 49: Standford 2015 week6
Page 50: Standford 2015 week6
Page 51: Standford 2015 week6
Page 52: Standford 2015 week6

//MARK: - // MARK: - Navigation

Page 53: Standford 2015 week6

font: Headline & Body

Page 54: Standford 2015 week6

cell點選樣式

Page 55: Standford 2015 week6

accessory樣式

Page 56: Standford 2015 week6

動態cell⾼高度

tableView.estimatedRowHeight = tableView.rowHeight tableView.rowHeight = UITableViewAutomaticDimension

Page 57: Standford 2015 week6

表格的多選self.tableView.allowsMultipleSelectionDuringEditing = YES; self.tableView.editing = YES;

Page 58: Standford 2015 week6

表格的delete

func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)

Page 59: Standford 2015 week6

表格cell順序調整

func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool

func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath)

Page 60: Standford 2015 week6

下拉更新的refresh

UITableViewController內建UIRefreshControl, 若是⾃自⼰己加⼊入的UITableView必須另外加上UIRefreshControl

Page 61: Standford 2015 week6

下拉更新的refresh

@IBAction func refresh(sender: AnyObject) { self.refreshControl?.endRefreshing() }

定義下拉更新觸發的method

endRefreshing: 結束更新,表格回到正常狀態

Page 62: Standford 2015 week6

Clear on Appearance

var clearsSelectionOnViewWillAppear: BoolUITableViewController:

設定⾴頁⾯面appear時,原本被select的cell是否取消選取,勾選表⽰示取消選取

⺫⽬目前在storyboard設定無效,預設會是取消選取, 若想改成不選取,必須另外從程式將clearsSelectionOnViewWillAppear設成false

Page 63: Standford 2015 week6

固定某個元件, 不隨表格scroll

⽅方法⼀一: 將table加到controller的view上

⽅方法⼆二: 將UITableViewController當成child controller, 可利⽤用storyboard的Container View

Page 64: Standford 2015 week6

固定某個元件, 不隨表格scroll

⽅方法三: 將元件加到UITableViewController的view上, 實作scrollViewDidScroll調整元件位置

override func scrollViewDidScroll(scrollView: UIScrollView) { var frame = self.blueView.frame frame.origin.y = 10 + scrollView.contentOffset.y self.blueView.frame = frame }

override func scrollViewDidScroll(scrollView: UIScrollView) { var frame = self.blueView.frame frame.origin.y = 10 + scrollView.contentOffset.y + 64 self.blueView.frame = frame }

當有透明的nav bar時

Page 65: Standford 2015 week6

cell swipe顯⽰示多個button

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]?

http://www.codebuddies.de/2015/03/14/swipeable-cells-in-about-5-minutes-swift/