setNeedsDisplay看我就懂宣旱!

圖片來源于網(wǎng)絡(luò)
前言:

setNeedsDisplay異步執(zhí)行的。它會自動調(diào)用drawRect方法锡搜,這樣可以拿到 UIGraphicsGetCurrentContext,就可以繪制了瞧掺。而setNeedsLayout會默認調(diào)用layoutSubViews耕餐,處理子視圖中的一些數(shù)據(jù)。

一辟狈、開始

我定義了一個UIView的子類肠缔,用于演示使用setNeedsDisplay,這個CircleView子類會在draw(_ rect: CGRect)方法內(nèi)簡單繪制一個圓哼转,它有一個顏色屬性明未,這是我們將要設(shè)置用來改變圓的顏色。

import UIKit

class CircleView: UIView {
    var color:UIColor = UIColor.red
    override func draw(_ rect: CGRect) {
        let path = UIBezierPath(ovalIn: rect)
        color.setFill()
        path.fill()
    }

}

注意: setNeedsDisplayInRect相當(dāng)于setNeedsDisplay壹蔓,除了它是指定視圖的特定矩形區(qū)域更新趟妥,而不是整個視圖需要顯示。

二佣蓉、配置屬性披摄、組件

應(yīng)用程序的下一部分是在故事板中配置一些UIKit組件亲雪,其中一個是CircleView

為了允許用戶更改顏色疚膊,我已經(jīng)定義了UIStepper控件义辕,我還添加一個按鈕,這可讓我們使用步進值來調(diào)整CircleView的顏色值寓盗。我不會詳細介紹如何配置storyboard灌砖,因為重點是了解setNeedsDisplay

@IBOutlet weak var stepper: UIStepper! //change value,default value is 120.
@IBOutlet weak var circleView: CircleView!

IBOutlets可以讓我們訪問circleViewStepper傀蚌。對于步進值的變化基显,有IBActions,最后,有一個colorChangeBtn喳张,它將調(diào)用一個未定義的方法changeColorFromStppers方法续镇。該方法將收集步進器的值,使用它創(chuàng)建一個UIColor销部,并設(shè)置circleView的color屬性摸航。


    func changeColorFromStppers() {
        let valueFloat = CGFloat(stepper.value)
        
        let color = UIColor(red:valueFloat/255.0, green:valueFloat/255.0, blue:valueFloat/255.0, alpha:1.0)
        circleView.color = color
    }

在viewDidLoad中,根據(jù)故事板中配置的步進器的默認值舅桩,我觸發(fā)了一組初始的圓形顏色酱虎。該changeColorFromStppers方法創(chuàng)建CGFloat的用于步進數(shù)的值,創(chuàng)建的UIColor擂涛,然后設(shè)置circleView.color读串。

    override func viewDidLoad() {
        super.viewDidLoad()

        self.changeColorFromStppers()
    }
三、思考

現(xiàn)在更改stepper的值撒妈,然后點擊colorChangeBtn按鈕恢暖,發(fā)現(xiàn)圓形顏色沒更新,這是什么原因呢狰右?

一般來說杰捂,使用框架控件,當(dāng)您設(shè)置屬性(如顯示標簽或值)時棋蚌,您將會使用該屬性嫁佳,這樣會導(dǎo)致重新繪制控件,因為系統(tǒng)會實現(xiàn)對控件drawRect方法的調(diào)用谷暮。而我們自定義了自己的UIView子類蒿往,所以我們需要處理影響顯示的控件的更新。在改變顏色的情況下湿弦,當(dāng)然需要我們自己控制重新繪制瓤漏。

根據(jù)上一篇文章setNeedsLayout和layoutIfNeeded看我就懂,所以我們在circleView.color = color之后添加了對setNeedsLayoutlayoutIfNeeded的調(diào)用,但結(jié)果同樣不會更新。類似地蔬充,旋轉(zhuǎn)設(shè)備也不會觸發(fā)重新繪制圓形俯在。這是因為視圖的緩存機制,即便視圖布局發(fā)生改變娃惯,也只是作為緩存。所以我們需要調(diào)用setNeedsDisplay肥败,明確地告訴系統(tǒng)必須重新繪制趾浅,從而顯示新的顏色
由此,我們需要考慮三個重要的原則:

1馒稍、在iOS中皿哨,視圖很明顯會被緩存。通常纽谒,給定的視圖可能會被繪制一次证膨,同時也不需要更新。
2鼓黔、即使視圖可能被移動或者有另一個視圖重疊央勒,也可能不需要重新繪制,因此您不能僅僅依靠已經(jīng)移動整個視圖或添加另一個視圖基于setNeedsLayoutupdateIfNeeded來導(dǎo)致重繪
3澳化、當(dāng)編寫重載drawRectUIView子類時崔步,需要在需要重繪時指示給系統(tǒng)。因為drawRect不能被手動調(diào)用缎谷,所以您需要使用setNeedsDisplay方法告訴系統(tǒng)完成繪圖井濒,

四、添加setNeedsDisplay

所以接下來列林,我們需要添加setNeedsDisplay()瑞你,有兩種方法

  • changeColorFromStppers添加
    完整代碼如下:
func changeColorFromStppers() {
    let valueFloat = CGFloat(stepper.value)
    
    let color = UIColor(red:valueFloat/255.0, green:100/255.0, blue:valueFloat/255.0, alpha:1.0)
    circleView.color = color
    //告訴系統(tǒng)需要重繪(Tell the system that circleView needs a redraw)
    circleView.setNeedsDisplay()
}
  • CircleView使用didSet屬性觀擦器
    代碼完整如下:
class CircleView: UIView {
    var color:UIColor = UIColor.red {
        didSet {
            setNeedsDisplay() //告訴系統(tǒng)重繪界面
        }
    }
    override func draw(_ rect: CGRect) {
        let path = UIBezierPath(ovalIn: rect)
        color.setFill()
        path.fill()
    }
}

這樣就能顯示了,希望大伙能多敲希痴,多體會者甲。
效果如下:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市润梯,隨后出現(xiàn)的幾起案子过牙,更是在濱河造成了極大的恐慌,老刑警劉巖纺铭,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寇钉,死亡現(xiàn)場離奇詭異,居然都是意外死亡舶赔,警方通過查閱死者的電腦和手機扫倡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人撵溃,你說我怎么就攤上這事疚鲤。” “怎么了缘挑?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵集歇,是天一觀的道長。 經(jīng)常有香客問我语淘,道長诲宇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任惶翻,我火速辦了婚禮姑蓝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吕粗。我一直安慰自己纺荧,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布颅筋。 她就那樣靜靜地躺著宙暇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪议泵。 梳的紋絲不亂的頭發(fā)上客给,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天,我揣著相機與錄音肢簿,去河邊找鬼靶剑。 笑死,一個胖子當(dāng)著我的面吹牛池充,可吹牛的內(nèi)容都是我干的桩引。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼收夸,長吁一口氣:“原來是場噩夢啊……” “哼坑匠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起卧惜,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤厘灼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后咽瓷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體设凹,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年茅姜,在試婚紗的時候發(fā)現(xiàn)自己被綠了闪朱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖奋姿,靈堂內(nèi)的尸體忽然破棺而出锄开,到底是詐尸還是另有隱情,我是刑警寧澤称诗,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布萍悴,位于F島的核電站,受9級特大地震影響寓免,放射性物質(zhì)發(fā)生泄漏退腥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一再榄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧享潜,春花似錦困鸥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至艺蝴,卻和暖如春猬腰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背猜敢。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工姑荷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缩擂。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓鼠冕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胯盯。 傳聞我的和親對象是個殘疾皇子懈费,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載:http://www.reibang.com/p/32fcadd12108 每個UIView有一個伙伴稱為l...
    F麥子閱讀 6,170評論 0 13
  • Core Animation基礎(chǔ) Core Animation 利用了硬件加速和架構(gòu)上的優(yōu)化來實現(xiàn)快速渲染和實時動...
    獨木舟的木閱讀 1,534評論 0 3
  • 本章中迄今為止的繪制實施例中大多會產(chǎn)生一個UIImage對象,主要是通過調(diào)用UIGraphicsBeginImag...
    shenzhenboy閱讀 1,364評論 0 4
  • --繪圖與濾鏡全面解析 概述 在iOS中可以很容易的開發(fā)出絢麗的界面效果博脑,一方面得益于成功系統(tǒng)的設(shè)計憎乙,另一方面得益...
    韓七夏閱讀 2,717評論 2 10
  • 今天是八月份的最后一天 沒有往常的秋高氣爽 浮動 float 特性: 1. float是有方向的 2. 盡可能的往...
    Cyril丶閱讀 206評論 0 0