Swift(十)UIView

更新:2018.05.24

整理了一下demo:SwiftDemo


UIView是UIKit框架里面最基礎(chǔ)的試圖類,UIView類定義了一個(gè)矩形的區(qū)域,并管理該區(qū)域內(nèi)的所有屏幕顯示。
iOS應(yīng)用中,每個(gè)視圖都要負(fù)責(zé)渲染試圖矩形區(qū)域的內(nèi)容,并響應(yīng)該區(qū)域中發(fā)生的事件,這一雙重行為意味著視圖是應(yīng)用程序與用戶交互的重要機(jī)制。

圖是在網(wǎng)上找的:

  • NSObject:NSObject是一個(gè)根類,幾乎所有的類都是沖它派生出來(lái)的,根類擁有所有類都有的方法,alloc、init等。
  • UIResponder:可以讓繼承它的類響應(yīng)移動(dòng)設(shè)備的觸碰事件,由于可能存在多個(gè)對(duì)象響應(yīng)同一事件,所以iOS將事件沿響應(yīng)鏈向上傳遞。
  • UIView:UIview是所有控件的父類,控件用于響應(yīng)用戶的交互,而UIView負(fù)責(zé)顯示和布局。
  • UIWindow: UIWindow提供了一個(gè)用于管理和顯示視圖的窗口。窗口提供一個(gè)描畫(huà)內(nèi)容的表面,是所有其他視圖的根容器。每個(gè)應(yīng)用程序通常都只有一個(gè)窗口。
  • UIControl:UIControl幾乎是所有交互控件的父類,如按鈕、滑塊、文本框等。所以UIControl負(fù)責(zé)根據(jù)碰觸事件出發(fā)響應(yīng)的動(dòng)作。

UIWindow

  • UIView視圖和UIWindow窗口是iOS應(yīng)用程序構(gòu)造洪湖界面的可視視圖。超扣為內(nèi)容顯示提供平臺(tái),而視圖負(fù)責(zé)絕大部分的內(nèi)容描述和響應(yīng)用戶交互。
  • 程序啟動(dòng)后,創(chuàng)建的第一個(gè)視圖就是UIWindow,接著創(chuàng)建視圖控制器的view,并把view放到UIWindow上,于是控制器的view就顯示在屏幕上了。
  • 當(dāng)view顯示到屏幕上之后,除非有特殊操作,不然就很少再使用到window了。
  • 盡量不要?jiǎng)?chuàng)建多個(gè)窗口,盡管iOS是支持多個(gè)窗口同時(shí)存在的。

1.UIView外觀

UIView外觀常用的主要有背景顏色、切邊、透明度、顯示與吟唱。

        let testView = UIView()
        // 坐標(biāo)
        testView.frame = CGRect(x: 100, y: 100, width: 50, height: 50)
        // 背景顏色
        testView.backgroundColor = UIColor.black
        // 是否切除子視圖超出部分
        testView.clipsToBounds = true
        // 透明度
        testView.alpha = 0.5
        // 是否隱藏視圖
        testView.isHidden = false
        // 添加到當(dāng)前視圖控制器
        view.addSubview(testView)

a. 上述代碼中,我們建立了一個(gè)位置在(100,100),寬高都是50的UIView視圖。frame的作用是確定視圖的位置及大小。

  • UIView的frame(origin,size)屬性:定義了一個(gè)矩形,描述UIView的大小和在父系坐標(biāo)系中的位置。
  • UIView的bounds(origin,size)屬性:同樣定義一個(gè)矩形,描述一個(gè)UIView的大小和自身坐標(biāo)系中的位置,通常bounds.origin的屬性是 (0,0),而bounds.sizeframes.size是一致的。
  • UIView的center屬性:用于確定一個(gè)視圖的中心位置,其參照系也是其俯視圖的坐標(biāo)系。在對(duì)視圖進(jìn)行放大、縮小或旋轉(zhuǎn)時(shí),center屬性不會(huì)變。

b. 設(shè)置背景顏色是黑色,UIColor是繼承自NSObject的一個(gè)儲(chǔ)存顏色的類,包含了顏色和透明度的值


可以看出,它提供了一些最常使用顏色的類方法。同時(shí)也有RGB設(shè)置顏色和透明度的方法

c. clipToBounds屬性用于限制子視圖的顯示范圍不能超過(guò)父視圖的顯示區(qū)域,如果設(shè)置為true,超出部分將被切除。

        let testView2 = UIView(frame: CGRect(x: 20, y: 20, width: 50, height: 50))
        testView2.backgroundColor = UIColor.green
        testView.addSubview(testView2)


代碼中我們?cè)?code>testView中又建立了一個(gè)同樣大小的testView2,坐標(biāo)在(20,20),可以看出,因?yàn)?code>testView中clipToBounds設(shè)置了true,所以testView2超出部分被切掉了。

d. alpha 負(fù)責(zé)視圖的透明度,上面的途中可以看出,黑色中透著紅色,是因?yàn)槲覀冊(cè)O(shè)置了0.5的透明度,也就是半透明狀態(tài)。透明度的取值范圍是0~1.0。
在視圖上添加透明度之后,會(huì)使子視圖也有相同的透明度。
如果當(dāng)前viewalpha是0,那么view及其子視圖會(huì)一同消失,不論子視圖的alpha是多少。
同時(shí),view會(huì)從響應(yīng)鏈中移除,而響應(yīng)鏈中的下一個(gè)會(huì)成為第一響應(yīng)者。

e.isHidden 負(fù)責(zé)視圖的隱藏與顯示,默認(rèn)是false。
如果當(dāng)前viewisHiddentrueview及其子視圖都會(huì)被隱藏,不論子視圖的isHidden是什么。
同時(shí),view會(huì)從響應(yīng)鏈中移除,而響應(yīng)鏈的下一個(gè)會(huì)成為第一響應(yīng)者。

2. UIView嵌套和層級(jí)關(guān)系

視圖可以通過(guò)嵌套的方式,組成復(fù)雜的層級(jí)結(jié)構(gòu)。

  • 視圖可能包含按鈕、標(biāo)簽、圖像等控件,這些控件被稱為子視圖,而包含他們的視圖被稱為父視圖。
  • 一個(gè)視圖可以包含任意數(shù)量的子視圖,通過(guò)為子視圖添加子視圖的方式,可以實(shí)現(xiàn)任意深度的嵌套。
  • 視圖在視圖層次中的組織方式?了屏幕上顯示的內(nèi)容,因?yàn)橹甘緢D總是被顯示在父視圖的上方,這個(gè)組織方式還決定了視圖如何響應(yīng)時(shí)間和變化。
  • 每個(gè)父視圖還負(fù)責(zé)管理其直接的子視圖,根據(jù)需要調(diào)整他們的位置和尺寸,以及響應(yīng)他們沒(méi)有處理的事件。
方法名 描述
removeFromSuperview() 將子視圖從父視圖中刪除。
addSubview(view:) 添加視圖,加在父視圖層級(jí)結(jié)構(gòu)的最上層。
insertSubview(view:,at:) 在指定位置插入視圖
insertSubview(view:,belowSubview:) 將視圖添加到指定視圖的下方。
insertSubview(view:,aboveSubview:) 將視圖添加到指定是圖的上方。
exchangeSubview(at:,withSubviewAt:) 交換2個(gè)指定位置的子視圖在父視圖中的位置。
bringSubview(toFront:) 將指定子視圖移動(dòng)到最前面。
sendSubview(toBack:) 將指定子視圖移動(dòng)到最后面。

這邊就不上代碼了。

3.UIView交互屬性

  • 設(shè)置UIViewuserInteractionEnabled屬性,可以設(shè)置用戶的交互特性,這個(gè)屬性決定UIView是否接受并響應(yīng)用戶的交互。
  • 當(dāng)屬性值為false時(shí),UIView會(huì)忽略那些發(fā)生在其自身的如觸摸、鍵盤等用戶事件,并將這些事件從消息列表中移除。
  • 當(dāng)屬性值為true時(shí),這些用戶事件會(huì)正常派發(fā)至UIView本身,UIView會(huì)按照之前注冊(cè)的事件處理方法來(lái)響應(yīng)相應(yīng)的事件。
        let touchView = UIView.init(frame: CGRect(x: 100, y: 240, width: 150, height: 150))
        touchView.isUserInteractionEnabled = true
        touchView.backgroundColor = UIColor.black
        view.addSubview(touchView)
       
        let tap = UITapGestureRecognizer(target: self, action: #selector(touchViewClick))
        touchView.addGestureRecognizer(tap)

  func touchViewClick() {
        print("You touched me!!!")
    }

a. 上面代碼中,我們創(chuàng)建了一個(gè)touchView視圖,設(shè)置背景顏色為黑色,并給它添加了一個(gè)點(diǎn)擊手勢(shì)。
b. 當(dāng)點(diǎn)擊touchView的時(shí)候,會(huì)輸出You touched me!!!
c. 如果將isUserInteractionEnabled屬性設(shè)置為false,那么這個(gè)方法將不被執(zhí)行。

4.UIView變形操作

  • CGAffine Transform仿射轉(zhuǎn)換結(jié)構(gòu)體代表了一種用于放射變換的矩陣。
  • 結(jié)構(gòu)體的參數(shù)指定了從一個(gè)坐標(biāo)系的點(diǎn)轉(zhuǎn)化成另外一個(gè)坐標(biāo)系的點(diǎn)的規(guī)則。
  • 仿射變換是一種特殊類型的映射,保留在一個(gè)路徑中的平行線,但不一定保留長(zhǎng)度或角度。
  • 我們通常不會(huì)創(chuàng)建一個(gè)仿射變換,只需要根據(jù)現(xiàn)有的參數(shù),修改現(xiàn)有的仿射變換。

幾種常用的仿射變換:

名稱 說(shuō)明
translatedBy(x:,y:) 對(duì)已存在的矩陣進(jìn)行平移
scaledBy(x:,y:) 對(duì)已存在的矩陣進(jìn)行縮放
rotated(by:) 對(duì)已存在的矩陣進(jìn)行旋轉(zhuǎn)
inverted() 對(duì)已存在的矩陣進(jìn)行反轉(zhuǎn)
concatenating(t2:) 對(duì)仿射效果進(jìn)行疊加操作
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
        
        let view_t = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
        view_t.backgroundColor = UIColor.black
        view_t.center = view.center
        view.addSubview(view_t)
        
        let transform = view_t.transform
        // 向下平移200像素
        view_t.transform = transform.translatedBy(x: 0, y: 200)
    }

a. 上面代碼中,我們創(chuàng)建了一個(gè)view_t,寬度200高度50,位置在屏幕中間。顏色為黑色。


b. 在沒(méi)有添加transform時(shí),跑一下項(xiàng)目會(huì)發(fā)現(xiàn)view_t在屏幕中間顯示,后面我們加了transform的平移操作,跑一下項(xiàng)目會(huì)發(fā)現(xiàn)view_t向下平移了200。


c.現(xiàn)在我們把平移換成縮放仿射變換,讓它縮小一半:

        view_t.transform = transform.scaledBy(x: 0.5, y: 0.5)


跑一下項(xiàng)目會(huì)發(fā)現(xiàn)view_t縮小了一半,同理,如果是放大的話,就讓x和y的值按照要求增大,比如放大到1.5倍:

        view_t.transform = transform.scaledBy(x: 1.5, y: 1.5)

d. 接下來(lái)我們?cè)诳匆幌?strong>旋轉(zhuǎn)仿射變換,依然用這個(gè)例子,更換transform,為rotate,比如旋轉(zhuǎn)45度:

        view_t.transform = transform.rotated(by: CGFloat(Double.pi/4))

Double.pi是圓周率π,OC中一般是M_PI,但在這報(bào)黃,系統(tǒng)推薦用這個(gè)。

e. 繼續(xù)我們看一下斜切仿射變換,我們上面用的平移、縮放、旋轉(zhuǎn)都是系統(tǒng)封裝好的,系統(tǒng)并沒(méi)有提供類似于CGAffineRransformRoate方法的斜切操作方法。所以我們要使用transforminit方法自己創(chuàng)建。

    public init(a: CGFloat, b: CGFloat, c: CGFloat, d: CGFloat, tx: CGFloat, ty: CGFloat)
參數(shù)名 說(shuō)明
a 水平方向上的縮放因子
b 水平方向上的斜切因子
c 垂直方向上的斜切因子
d 垂直方向上的縮放因子
tx 水平方向上的位移因子
ty 垂直方向上的位移因子

我們可以在代碼中這樣設(shè)置

        transform.a = 1.0
        transform.b = 0.5
        transform.c = 0.5
        transform.d = 1.0
        transform.tx = 0.0
        transform.ty = 0.0
        view_t.transform = transform
  • 其中a和d的值都是1,即保持縮放大小不變
  • b和c都是0.5 即在水平和垂直方向進(jìn)行斜切操作
  • tx和ty的值都是0,即水平和垂直方向不進(jìn)行位移

OK,UIView的方面大概先到這里。剛開(kāi)始截圖的時(shí)候圖片是白色的,不是很清晰,換了背景色重新截圖的。

最后編輯于
?著作權(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)容

  • 曾經(jīng)有人這么說(shuō)過(guò),在iphone里你看到的,摸到的,都是UIView,所以UIView在iphone開(kāi)發(fā)里具有非常...
    我是一只攻城獅_ifYou閱讀 706評(píng)論 0 2
  • 7、不使用IB是,下面這樣做有什么問(wèn)題? 6、請(qǐng)說(shuō)說(shuō)Layer和View的關(guān)系,以及你是如何使用它們的。 1.首先...
    AlanGe閱讀 988評(píng)論 0 1
  • 在iOS開(kāi)發(fā)中經(jīng)常會(huì)涉及到觸摸事件。本想自己總結(jié)一下,但是遇到了這篇文章,感覺(jué)總結(jié)的已經(jīng)很到位,特此轉(zhuǎn)載。作者:L...
    WQ_UESTC閱讀 6,237評(píng)論 4 26
  • 好奇觸摸事件是如何從屏幕轉(zhuǎn)移到APP內(nèi)的?困惑于Cell怎么突然不能點(diǎn)擊了?糾結(jié)于如何實(shí)現(xiàn)這個(gè)奇葩響應(yīng)需求?亦或是...
    Lotheve閱讀 59,476評(píng)論 51 604
  • 李亞鵬的子女教育觀摘錄: 我希望我的女兒能成為一個(gè)有愛(ài)、有才情、不輕易被打敗的人。 有愛(ài): 上帝給了你傷痕,我要讓...
    好西好閱讀 429評(píng)論 0 0

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