Stanford CS193p iOS開(kāi)發(fā)課程筆記(八)

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.contentOffset

  • zoom 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")

    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • *7月8日上午 N:Block :跟一個(gè)函數(shù)塊差不多,會(huì)對(duì)里面所有的內(nèi)容的引用計(jì)數(shù)+1,想要解決就用__block...
    炙冰閱讀 2,711評(píng)論 1 14
  • 一.UITextField屬性 0.enablesReturnKeyAutomatically 默認(rèn)為No,如果設(shè)...
    奮斗ing0310閱讀 1,765評(píng)論 0 2
  • 介紹 在這個(gè)教程中,我們會(huì)做一個(gè)可以渲染Mandelbrot Set的應(yīng)用程序,我們可以縮放和平鋪它來(lái)看分形那令人...
    木易林1閱讀 795評(píng)論 1 0
  • 默默買(mǎi)好所需要的東西,困到不行。 有時(shí)想想也累,從上周開(kāi)始,就開(kāi)始逛,到今晚,進(jìn)行二次淘汰,因?yàn)橛行┪锲窙](méi)付定...
    williie007閱讀 151評(píng)論 0 0
  • ——馬建國(guó) 老是認(rèn)為你只是個(gè)“丑女婿” 沒(méi)怎么把你放在心里 真沒(méi)想到 由于你的努力和堅(jiān)持 成為...
    策馬奔騰2閱讀 329評(píng)論 0 3

友情鏈接更多精彩內(nèi)容