2015年12月12日
Stanford CS193p第九課 Scroll View,Multithreading
ScrollView
添加ScrollView
1.設(shè)置其滑動(dòng)區(qū)域(最大可顯示區(qū)域)scrollView. contentSize = CGSize(width: 3000, height:2000)
2.設(shè)置位置及大小logo.frame = CGRect(x:2700, y:50, width:120, height: 180)
3.添加scrollView.addSubview(logo)獲取正在顯示的區(qū)域
利用ScrollView的contentOffset屬性即可let upperLeftOfVisible:CGPoint = scrollView.contentOffsetzoom in 放大/縮小ScrollView也可以進(jìn)行放大和縮小
1.設(shè)置代理,實(shí)現(xiàn)viewForZoomingInScrollView方法func viewForZoomingInScrollView(sender: UIScrollView) -> UIView
2.設(shè)置zoom in的最大值和最小值ScrollView.minimumZoomScale = 0.5 //最小縮小為原來(lái)的1/2 ScrollView.maxmumZoomScale = 2.0 //最大放大到原來(lái)的2倍
3.利用代碼進(jìn)行縮放設(shè)置
func setZoomScale(CGFloat, animated: Bool)
func zoomToRect(CGRect, animated: Bool)```
####Multithreading多線程
- Queues
在iOS里有多重隊(duì)列,每個(gè)隊(duì)列就相當(dāng)于一個(gè)函數(shù)隊(duì)列,基礎(chǔ)的閉包在等待運(yùn)行.每個(gè)隊(duì)列都有一個(gè)自己的線程去運(yùn)行這些隊(duì)列、去處理隊(duì)列里的東西.這造就了多線程環(huán)境
- Main Queue
1.Main Queue是什么?
主隊(duì)列是一個(gè)串行隊(duì)列,這說(shuō)明主隊(duì)列依次從隊(duì)列里拉出一個(gè)函數(shù).它從來(lái)不會(huì)同一時(shí)間運(yùn)行兩個(gè)函數(shù).所有的UI活動(dòng)都必須發(fā)生在主隊(duì)列.<br />
2.如何獲得Main Queue
```swift
let mainQ: dispatch_queue_t = dispatch_get_main_queue()
let mainQ: NSOperationQueue = NSOperationQueue.mainQueue()
//以上兩種方法都可獲得Main Queue
dispatch_async(notTheMainQueue) {
//此處跳出主隊(duì)列,獲取其他隊(duì)列,在此一般添加一些不阻塞UI的代碼,如DEMO中的加載URL,已實(shí)現(xiàn)程序的順暢運(yùn)行
dispatch_async(dispatch_get_main_queue()) {
//返回主隊(duì)列,此時(shí)已經(jīng)完成了上面對(duì)URL的加載,這時(shí)再來(lái)更新UI
}
}
- Other Queues
如何獲得
1.向系統(tǒng)申請(qǐng)一個(gè)恰當(dāng)?shù)膕ervice來(lái)獲取隊(duì)列
QOS_CLASS_USER_INTERACTIVE //最高優(yōu)先級(jí),立即執(zhí)行
QOS_CLASS_USER_INITIATED //優(yōu)先級(jí)較高,但加載會(huì)占用較長(zhǎng)時(shí)間
QOS_CLASS_UTILITY //較低優(yōu)先級(jí)
QOS_CLASS_BACKGROUND //最低優(yōu)先級(jí),可在后臺(tái)進(jìn)行處理,與用戶的操作無(wú)關(guān)
let qos = Int(以上四個(gè)QOS的其中之一.rawValue)
2.創(chuàng)建隊(duì)列
let queue = dispatch_get_global_queue(qos,0)
3.進(jìn)行隊(duì)列的操作,實(shí)現(xiàn)代碼即可
CassiniDemo
<br />

Cassini.png
知識(shí)點(diǎn)
1.圖片加載功能的實(shí)現(xiàn)
2.ScrollView的使用
3.多線程操作的實(shí)現(xiàn)代碼如下
//ViewController.swift
import UIKit
class ViewController: UIViewController {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let ivc = segue.destinationViewController as? ImageViewController {
if let identifier = segue.identifier {
switch identifier {
case "Earth": ivc.imageURL = DemoURL.NASA.Earth
ivc.title = "Earth"
case "Saturn": ivc.imageURL = DemoURL.NASA.Saturn
ivc.title = "Saturn"
case "Cassini": ivc.imageURL = DemoURL.NASA.Cassini
ivc.title = "Cassini"
default: break
}
}
}
}
}
//ImageViewController.swift
import UIKit
class ImageViewController: UIViewController,UIScrollViewDelegate {
//Model
var imageURL: NSURL? {
didSet {
image = nil
//如果不在這個(gè)頁(yè)面時(shí),就不進(jìn)行圖片下載
if view.window != nil {
fetchImage()
}
}
}
@IBOutlet weak var spinner: UIActivityIndicatorView!
//根據(jù)URL提取圖片,并把圖片載入到imageView中
private func fetchImage() {
spinner.startAnimating()
if let url = imageURL {
let qos = Int(QOS_CLASS_USER_INITIATED.rawValue)
dispatch_async(dispatch_get_global_queue(qos, 0)) { () -> Void in
let imageData = NSData(contentsOfURL: url)
//此處進(jìn)行圖片數(shù)據(jù)的加載,將會(huì)耗費(fèi)很長(zhǎng)時(shí)間,故將他放到主線程外.如果不分線程,點(diǎn)擊button后在圖片被加載完畢之前都不會(huì)跳轉(zhuǎn)到detail視圖(卡頓感很強(qiáng)),分了線程之后,點(diǎn)擊button即可直接跳轉(zhuǎn)至detail視圖,也可從detail返回.
//這里涉及到UI得元素,故需要在主線程進(jìn)行處理,利用dispatch_async(dispatch_get_main_queue())代碼使其回到主線程
dispatch_async(dispatch_get_main_queue()) {
if url == self.imageURL { //確保了用戶在點(diǎn)擊button載入其他圖片時(shí)不會(huì)出現(xiàn)上次點(diǎn)擊后未加載完成的圖片
if imageData != nil {
self.image = UIImage(data: imageData!)
} else {
self.image = nil
}
}
}
}
}
}
@IBOutlet weak var scrollView: UIScrollView! {
didSet {
scrollView.contentSize = imageView.frame.size
scrollView.delegate = self
scrollView.minimumZoomScale = 0.03
scrollView.maximumZoomScale = 1.0
}
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return imageView
}
private var imageView = UIImageView()
private var image: UIImage? { //利用計(jì)算屬性相當(dāng)于在此創(chuàng)建了一個(gè)setImage的方法
get { return imageView.image }
set {
imageView.image = newValue
imageView.sizeToFit()
scrollView?.contentSize = imageView.frame.size
spinner?.stopAnimating()
}
}
override func viewDidLoad() {
super.viewDidLoad()
scrollView.addSubview(imageView)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//當(dāng)界面要顯示時(shí),如果圖片為空,則進(jìn)行圖片進(jìn)行下載.如果已經(jīng)進(jìn)行了下載,則不重復(fù)下載
if image == nil {
fetchImage()
}
}
}
//DemoURL.swift
import Foundation
struct DemoURL {
static let Stanford = NSURL(string: "http://comm.stanford.edu/wp-content/uploads/2013/01/stanford-campus.png")
struct NASA {
static let Cassini = NSURL(string: "http://gb.cri.cn/mmsource/images/2005/03/10/na050310113.jpg")
static let Earth = NSURL(string: "http://img.taopic.com/uploads/allimg/121226/234737-12122615230144.jpg")
static let Saturn = NSURL(string: "http://m2.quanjing.com/2m/mf002/mf700-00017374.jpg")
}
}