接上一節(jié)洛心,我們了解到簡(jiǎn)簡(jiǎn)單單的幾行代碼就可以寫出一個(gè)動(dòng)畫乳讥,本節(jié)將進(jìn)一步對(duì)IOS的純代碼UI開發(fā)做簡(jiǎn)單的入門考蕾。
? ? 什么是UI開發(fā):這是給小白解釋掖肋,熟人請(qǐng)繞過。手機(jī)的App可以認(rèn)為是由一個(gè)一個(gè)頁(yè)面組成蹂楣。就好比你現(xiàn)在正在看的這個(gè)網(wǎng)頁(yè)俏站,就可以認(rèn)為是一個(gè)頁(yè)面,如果點(diǎn)擊了這個(gè)網(wǎng)頁(yè)上的一個(gè)按鈕痊土,就會(huì)跳到另外一個(gè)地方肄扎,這就跳到另外一個(gè)頁(yè)面了。編寫這些頁(yè)面內(nèi)容赁酝,就叫UI開發(fā)犯祠。UI開發(fā)直接影響用戶的體驗(yàn),在移動(dòng)App開發(fā)中占有很重的比例赞哗,每一個(gè)IOS開發(fā)人員都必須掌握雷则。本節(jié)介紹一種UI開發(fā)方法:用純代碼來寫UI。
一肪笋、創(chuàng)建工程
打開Xcode創(chuàng)建一個(gè)IOS的"Single View App"工程月劈,不懂創(chuàng)建的人請(qǐng)參看"IOS開發(fā)入門之二——第一個(gè)App",創(chuàng)建后的界面如下圖所示:
二藤乙、工程目錄簡(jiǎn)介
? ? 上圖界面中左側(cè)有很多的文件夾猜揪,大致了解一些這些文件夾的作用:
? ? 外側(cè)的四個(gè)大文件夾:
? ? 1. Products: 主要用于mac電腦開發(fā),IOS開發(fā)用不到坛梁。
? ? 2. MyFirstAppTests: 用于單元測(cè)試而姐。
? ? 3. MyFirstAppUITests: 用于UI測(cè)試。
3. MyFirstApp: IOS開發(fā)的內(nèi)容主要都是存放在這個(gè)文件夾中划咐。
MyFirstApp這個(gè)文件夾又包含:
? ? 3.1? AppDelegate.swift:代表應(yīng)用程序拴念,App初始化需要的內(nèi)容都在這里做,App是從這里開始啟動(dòng)的褐缠,這個(gè)文件暫時(shí)不做深入政鼠。
3.2 ViewController.swift: 這是IOS視圖控制器,其實(shí)說白了就是一個(gè)頁(yè)面的容器队魏,我們編寫UI代碼都要寫在這個(gè)容器里公般,這是本節(jié)重點(diǎn)關(guān)注的文件。
? ? 3.3 Main.storyboard: storyboard文件可以幫助我們用比較直觀的方式來快速的開發(fā)UI胡桨,通過這個(gè)文件我們可以看到我們?cè)O(shè)計(jì)的頁(yè)面長(zhǎng)什么樣子官帘。比如,我們要在頁(yè)面上添加一張圖片昧谊,我們只要將一個(gè)圖片的控件直接拉到storyboard上刽虹,就可以看到這個(gè)圖片在頁(yè)面上到底是大是小,位置在哪里等等揽浙。這是IOS推薦的UI開發(fā)模式状婶。有人要問了意敛,那我們還要用代碼寫UI,不是很麻煩嗎膛虫?其實(shí)這兩種方式寫UI各有優(yōu)缺點(diǎn)草姻,我們可以取長(zhǎng)補(bǔ)短,這在后面講到storyboard的時(shí)候再討論稍刀。Main.storyboard顧名思義就是主頁(yè)面撩独。storyboard設(shè)計(jì)后效果如下圖。
4. Assets.xcassets: 這個(gè)文件夾主要用于存放資源文件账月,比如圖片
5. LauchScreen.storyboard: 顧名思義就是啟動(dòng)頁(yè)面综膀,在打開一個(gè)App的時(shí)候,一般不會(huì)直接跳到主頁(yè)面局齿,經(jīng)常會(huì)先來個(gè)某某公司或則廣告圖片什么的剧劝,這就是啟動(dòng)頁(yè)。
? ? 6. info.plist: 這個(gè)文件是項(xiàng)目的配置文件抓歼。比如主頁(yè)面是哪個(gè)頁(yè)面讥此,所以Main.storyborad也不一定就是主頁(yè)面,因?yàn)樵谶@里可以修改谣妻。
三萄喳、認(rèn)識(shí)視圖
? ? 下面我們重點(diǎn)關(guān)注ViewController.swift這個(gè)文件,單擊這個(gè)文件蹋半,得到如下界面(紅框和箭頭是我做的標(biāo)記)他巨,下面逐一解釋代碼的作用
import UIKit:UIKit是IOS提供給我們專門用于編寫UI代碼的庫(kù),import是導(dǎo)入的意思减江,導(dǎo)入U(xiǎn)IKit這個(gè)庫(kù)后就可以在后續(xù)代碼中用其提供的類來寫UI染突。以后要使用第三方提供的庫(kù),類似也要這么導(dǎo)入辈灼。
? ? ViewController:UIKit庫(kù)中一個(gè)重要的類觉痛,顧名思義“視圖控制器”∫鹦荩可以先這么認(rèn)為吧,一個(gè)ViewController代表一個(gè)頁(yè)面的容器手蝎。也就是一個(gè)頁(yè)面對(duì)應(yīng)一個(gè)ViewController榕莺。所以很明顯,我們的UI代碼應(yīng)該寫在ViewController類里面棵介。
? ? viewDidLoad(): 這是UIViewController中的一個(gè)方法钉鸯,代表頁(yè)面已經(jīng)初始化完畢,這時(shí)頁(yè)面還是空白的邮辽,可以往頁(yè)面中添加其他的UI元素了唠雕,比如圖片贸营、文字。我們要添加的UI代碼都是寫在紅色箭頭所指的地方岩睁。每個(gè)頁(yè)面都有一個(gè)完整的生命周期钞脂,從它開始被創(chuàng)建一直到它被銷毀回收,UIViewController還提供很多的方法捕儒,對(duì)應(yīng)這些不同的生命階段冰啃,有興趣可以自己查找學(xué)習(xí),在這里不做介紹刘莹。
四阎毅、UIView
? ? UIView是UIKit庫(kù)中視圖的基類,代表頁(yè)面中的一個(gè)塊点弯,如下圖大紅框框中的部分就是一個(gè)頁(yè)面扇调,而其中的紅色的塊就是一個(gè)UIView。
? ? 1. 屬性和布局?
? ? 我們對(duì)視圖最關(guān)心的有兩點(diǎn):
? ? a) 它長(zhǎng)什么樣:這稱為視圖的屬性抢肛,比如是什么顏色狼钮、是否有邊框、邊框的顏色雌团、邊框的大小等
? ? b)它應(yīng)該放在頁(yè)面的哪個(gè)位置:這就是布局燃领,布局有兩種方法。一種使用frame锦援,另一種是用AutoLayout猛蔽。
(1)屬性
? ? 對(duì)于以后要用到的其他更高級(jí)的視圖控件,比如UILabel(專門顯示文字)灵寺、UIImageView(專門顯示圖片)曼库、UIButton(按鈕)等都是類似的。只是他們有更多的屬性而已略板。我們學(xué)習(xí)這些視圖毁枯,無非就是熟悉他們的屬性和布局,因此可以舉一反三叮称。
? ? 下面是一段最簡(jiǎn)單的例子:
let purpleView = UIView()?
purpleView.backgroundColor=UIColor.purple?
purpleView.frame=CGRect(x: 0, y: 100, width: 150, height: 150)?
view.addSubview(purpleView)?
可以拷貝到如下圖所示的位置(以后的代碼都是拷貝到類似的位置种玛,就不再貼出這些圖):
? ? let purpleView = UIView() //這句是創(chuàng)建一個(gè)視圖
? ? purpleView.backgroundColor = UIColor.purple //這句是將視圖的背景色設(shè)置為紫色
? ? purpleView.frame = CGRect(x: 0, y: 100, width: 150, height: 150) //這句是設(shè)置視圖的大小和位置:x:0表示視圖與頁(yè)面的左邊距離為0,y:150表示視圖與頁(yè)面的上邊距離為150瓤檐,width:150代表視圖寬度為150赂韵,height:150代表視圖的高度為150
view.addSubview(purpleView) //這句是表示將purpleView這個(gè)視圖添加到的頁(yè)面里
? ? 寫完這些代碼就可以點(diǎn)擊運(yùn)行App了,效果即是上面的紅色方塊圖挠蛉。
? ? IOS用//來注釋代碼祭示,可以用這個(gè)方法將臨時(shí)不用的代碼注釋起來,也可以用來對(duì)代碼進(jìn)行說明谴古。被//注釋后的代碼在程序運(yùn)行時(shí)质涛,將不會(huì)執(zhí)行稠歉。如下圖綠色部分的代碼就是將臨時(shí)不用的代碼注釋起來。
(2)布局
? ? 還可以用自動(dòng)布局AutoLayout的約束方式來限制視圖的位置:
? ? ? ? //創(chuàng)建一個(gè)視圖?
letredView = UIView()?
? ? ? ? //禁止將AutoresizingMask轉(zhuǎn)化為Constraints?
redView.translatesAutoresizingMaskIntoConstraints = false?
? ? ? ? // 背景色為紅色?
redView.backgroundColor = UIColor.red?
? ? ? ? // 將視圖添加到頁(yè)面中?
? ? ? ? view.addSubview(redView)?
? ? ? ? //創(chuàng)建約束汇陆,注意:要在視圖添加到其父容器(在此為頁(yè)面)后怒炸,才能進(jìn)行約束設(shè)置,否則App會(huì)奔潰?
? ? ? ? //寬度約束?
letwidthConstraint = NSLayoutConstraint(item: redView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 150)?
? ? ? ? //高度約束?
letheightConstraint = NSLayoutConstraint(item: redView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 150)?
? ? ? ? //頂部約束?
lettopConstraint = NSLayoutConstraint(item: redView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 100)?
? ? ? ? //左側(cè)約束?
letleftConstraint = NSLayoutConstraint(item: redView, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: 150)?
? ? ? ? //在頁(yè)面中添加多個(gè)約束?
? ? ? ? view.addConstraints([widthConstraint,heightConstraint,leftConstraint,topConstraint])?
? ? 用自動(dòng)布局AutoLayout的約束來設(shè)置視圖的位置是比較靈活的瞬测,但是IOS系統(tǒng)提供的這種寫法横媚,明顯太繁瑣。所以一般使用第三方提供的SnapKit庫(kù)來簡(jiǎn)化代碼的寫法月趟,有興趣的人可以查閱相關(guān)資料灯蝴,不懂如何導(dǎo)入第三方庫(kù)的可以參考:IOS如何導(dǎo)入第三方庫(kù)-CocoaPods
2. 動(dòng)畫
上面談到的屬性和布局都是設(shè)置靜止不動(dòng)的內(nèi)容,有時(shí)我們想讓這些圖片或文字能夠動(dòng)起來孝宗,這樣看起來比較有趣穷躁。"IOS開發(fā)入門之三——從一個(gè)動(dòng)畫開始"那節(jié)我們只是簡(jiǎn)單的演示如何產(chǎn)生一個(gè)動(dòng)畫,沒有對(duì)代碼做任何解釋因妇,下面將對(duì)動(dòng)畫代碼做詳細(xì)說明问潭。主要代碼如下:
animView.frame=CGRect(x:0,y:0,width:100,height:100) //設(shè)置動(dòng)畫視圖的尺寸?
animView.center=view.center //動(dòng)畫視圖放在父視圖的正中央?
animView.backgroundColor=UIColor.green//動(dòng)畫視圖的背景色設(shè)置為綠色?
view.addSubview(animView)//將動(dòng)畫視圖添加到父視圖(即頁(yè)面)?
UIView.animate(withDuration: 2,delay:1,usingSpringWithDamping:0.2,initialSpringVelocity:0,options:[.repeat,.autoreverse], animations:{?
self.animView.transform=CGAffineTransform(scaleX: 0.5, y: 0.5)//將動(dòng)畫視圖大小縮小為原來的一半?
},completion:nil)?
? ? 前面四行,是設(shè)置屬性和布局可以參看上面的婚被,不做說明狡忙。我們重點(diǎn)關(guān)注最后一個(gè)方法:
? ? UIView.animate()這個(gè)方法是UIView類提供的一個(gè)靜態(tài)方法,專門用于播放和控制視圖動(dòng)畫址芯。里面的參數(shù)有:
? ? withDuration: 2表示動(dòng)畫總的時(shí)長(zhǎng)為2秒
? ? delay:1表示動(dòng)畫延時(shí)1秒才開始播放灾茁,就是這段動(dòng)畫代碼被執(zhí)行后不馬上播放,而要等1秒鐘后才開始播放谷炸。
? ? usingSpringWithDamping:0.2彈簧動(dòng)畫的阻尼值北专,也就是相當(dāng)于摩擦力的大小,該屬性的值從0.0到1.0之間旬陡,越靠近0拓颓,阻尼越小,彈動(dòng)的幅度越大描孟,反之阻尼越大驶睦,彈動(dòng)的幅度越小,如果大道一定程度匿醒,會(huì)出現(xiàn)彈不動(dòng)的情況啥繁。
? ? initialSpringVelocity:0彈簧動(dòng)畫的速率,或者說是動(dòng)力青抛。值越小彈簧的動(dòng)力越小,彈簧拉伸的幅度越小酬核,反之動(dòng)力越大蜜另,彈簧拉伸的幅度越大适室。這里需要注意的是,如果設(shè)置為0举瑰,表示忽略該屬性捣辆,由動(dòng)畫持續(xù)時(shí)間和阻尼計(jì)算動(dòng)畫的效果。
? ? options后面可以設(shè)置很多可選項(xiàng)此迅,.repeat這個(gè)選項(xiàng)表示動(dòng)畫是重復(fù)的汽畴,.autoreverse這個(gè)選項(xiàng)表示動(dòng)畫播放完畢后會(huì)自動(dòng)倒播,注意這些選項(xiàng)前面要加一個(gè)點(diǎn)耸序。
? ? animations:{}這個(gè)大括號(hào)里面我們要指定視圖最終屬性值忍些。比如我們要讓一個(gè)原來透明度為1的視圖慢慢變?yōu)橥该鞫葹?.5,這個(gè)過程我們不需要關(guān)心坎怪,我們只要在這個(gè)大括號(hào)中將視圖最終0.5這個(gè)值設(shè)置好就行了罢坝。系統(tǒng)會(huì)根據(jù)視圖最初的透明度以及我們?cè)O(shè)置的這個(gè)0.5自動(dòng)生成中間值并用這些值來控制完成動(dòng)畫過程。也就是說搅窿,我們代碼只要告訴系統(tǒng)嘁酿,視圖最終的屬性值是多少系統(tǒng)就會(huì)為我們自動(dòng)生成這些動(dòng)畫過程。
? ? scanX:0.5男应,y:0.5表示這是一個(gè)縮放動(dòng)畫闹司,并且視圖在X方向縮小為原來的一半,Y方向也縮小為原來的一半沐飘,總體看就是方塊整體慢慢縮小一半游桩。
2.1 動(dòng)畫類型
? ? 按照動(dòng)作,動(dòng)畫可分為以下幾個(gè)類型:
? ? (1)平移:? ? ?
self.animView.transform=CGAffineTransform(translationX: -200, y: 20)?
? ? translationX: -200, y: 0表示視圖向左移動(dòng)200距離薪铜,同時(shí)向下移動(dòng)20距離众弓。x正值表示向右移動(dòng),負(fù)值表示向左移動(dòng)隔箍;y正值表示向下移動(dòng)谓娃,負(fù)值表示向上移動(dòng)。
? ? (2)縮放:
self.animView.transform=CGAffineTransform(scaleX: 0.5, y: 0.5)?
? ? scanX:0.5蜒滩,y:0.5表示視圖在x方向縮小為原來的一半滨达,y方向也縮小為原來的一半,總體看就是方塊整體慢慢縮小一半俯艰。x和y的值一般要大于等于0
? ? (3)旋轉(zhuǎn):? ?
self.animView.transform=CGAffineTransform(rotationAngle:CGFloat.pi/4)?
? ? rotaionAngle:CGFloat.pi/4表示順時(shí)針旋轉(zhuǎn)45度捡遍,CGFloat.pi/4代表旋轉(zhuǎn)的角度。
2.1 組合動(dòng)畫
有的人說了:我想同時(shí)變可以嗎竹握?當(dāng)然可以啦画株。要幾個(gè)動(dòng)畫一起來可以這樣寫:
let scale=CGAffineTransform(scaleX:0.6,y:0.6)//縮小到原來的0.6倍?
letrotation=CGAffineTransform(rotationAngle:CGFloat.pi/4)//順時(shí)針旋轉(zhuǎn)45度?
self.animView.transform=rotation.concatenating(scale)?
用concatenating()這個(gè)方法,你想套幾個(gè)動(dòng)畫都可以,比如還有一個(gè)平移動(dòng)畫可以這樣寫:
let transY=CGAffineTransform(translationX: 0, y: 150)//向下移動(dòng)150的距離?
letscale=CGAffineTransform(scaleX:0.6,y:0.6)//縮小到原來的0.6倍?
letrotation=CGAffineTransform(rotationAngle:CGFloat.pi/4)//順時(shí)針旋轉(zhuǎn)45度?
self.animView.transform=transY.concatenating(rotation.concatenating(scale))?
需要更多資料的人谓传,請(qǐng)聯(lián)系vx:1914532832蜈项,請(qǐng)備注:iOS開發(fā)。