iOS SwiftUI 入門

目前swiftUI最低支持iOS13,蘋果還在不斷升級(jí)完善,目前還不成熟,因?yàn)楝F(xiàn)在widget必須用swiftUI布局,所以有幸把swiftUI應(yīng)用到項(xiàng)目。當(dāng)我寫swiftUI的demo時(shí)感覺這東西好簡(jiǎn)單EZ,但是真到了項(xiàng)目中是各種坑

編輯代碼的兩種方式

1.代碼
2.preview畫布,拖拽控件,檢查器,inspector

因?yàn)閜review有時(shí)有問題,也不方便調(diào)試,需要維護(hù)一套假數(shù)據(jù),所以一般用代碼。

布局

swiftUI控件大多為結(jié)構(gòu)體

基本布局需要三個(gè)Stack:

HStack:水平布局,X軸
VStack:垂直布局,Y軸
ZStack:層疊布局,Z軸

可以看做是一個(gè)三維坐標(biāo)系

如果原來寫過flutter會(huì)對(duì)這個(gè)布局很熟悉,HStack相當(dāng)于Row,VStack相當(dāng)于Colum,但是swiftUI,HStack的alignment只有垂直對(duì)齊方式,VStack的alignment只有水平對(duì)齊方式,對(duì)齊方式是指Stack內(nèi)部元素的對(duì)齊方式,而不是Stack本身,Stack的實(shí)際大小是根據(jù)里面子視圖的大小來撐開的,如果Stack內(nèi)部只有一個(gè)元素,不管你設(shè)置任何對(duì)齊方式都是不起作用的
比如有一個(gè)需求,設(shè)置一個(gè)圖片緊貼左上角
EZ啊

VStack(alignment: .leading){
    Image("cloudy")
}

發(fā)現(xiàn)是居中,然后修改

ZStack(alignment:.topLeading){
    Image("cloudy")
}

還是居中沒變,是因?yàn)镾tack內(nèi)部就一張圖片,所以Stack就是圖片大小,需要撐開Stack才能設(shè)置內(nèi)部坐上對(duì)齊,修改如下

ZStack(alignment:.topLeading){
    Color(.clear)
    Image("cloudy")
}

用Color來撐開Stack,當(dāng)然也可以用別的方式,比如

VStack(alignment: .leading){
    HStack(alignment: .top){
        Image("cloudy")
        Spacer()
    }
    Spacer()
}

Spacer()撐開Stack

通過這三種Stack互相嵌套可以實(shí)現(xiàn)各種復(fù)雜的布局

需要注意的是;這三種Stack中的控件之間默認(rèn)是有間距的,所以需要指定間距,比如VStack(spacing:0)

布局通用屬性

細(xì)節(jié)的位置變化需要用到frame,offSet,position,padding,layoutPriority

frame只能指定寬高
.frame(minWidth: ,maxWidth: , minHeight: ,maxHeight:)用來給調(diào)用者一個(gè)大小限制,不能超出這個(gè)限制
idealWidth: ,idealHeight: 理想大小。必須配合.fixedSize(horizontal: true, vertical: false)才能生效,例如:
.frame(idealWidth: 300)
.fixedSize(horizontal: true, vertical: false)//設(shè)置在哪個(gè)方向強(qiáng)制生效,水平方向還是垂直方向

min寬高,類似于UIKit自動(dòng)布局的>=
max寬高,類似于UIKit自動(dòng)布局的<=

offSet:在視圖應(yīng)有的位置加上偏移量

position:在上層容器強(qiáng)制定位,相當(dāng)于UIKit里的frame(x,y),但是這里的x,y指的是視圖中心點(diǎn)的位置

padding:內(nèi)邊距
.padding(20)內(nèi)邊距都為20
.padding(.leading,20)左側(cè)內(nèi)邊距為20
.padding([.top, .leading],20)左側(cè)上側(cè)內(nèi)邊距為20

layoutPriority(0):視圖優(yōu)先級(jí),默認(rèn)為0

Space()撐開子控件到父控件的最大長度,經(jīng)常用,比如在屏幕最左邊和最右側(cè)顯示兩個(gè)文字對(duì)齊

HStack{
    Text("n")
    Spacer()
    Text("w")
}

獲取上層視圖空間大小,這個(gè)很常用

GeometryReader{proxy in
   Text(String(describing: proxy.size))         
}

常用控件

視圖分為:
緊湊視圖:大多數(shù)控件屬于這一類型,控件中的內(nèi)容決定控件的實(shí)際大小
貪婪視圖:Circel,Spacer,Color等,控件在父視圖范圍內(nèi)會(huì)盡可能多的去鋪滿剩余空間

一般有內(nèi)容的視圖是緊湊類型,容器類視圖為貪婪類視圖

Text
    .truncationMode(.middle)//設(shè)置超出文本的省略方式
    .lineLimit(1)//默認(rèn)不限制行數(shù)
    .font(.system(size: 85))//字體過大,超過顯示區(qū)域會(huì)整體消失,不顯示

Image:
如果圖片大小和顯示大小不一樣,需要手動(dòng)設(shè)置圖片的大小,需要先設(shè)置.resizable(),否則frame寬高不生效

    Image("forecast_icon_clound")
        .resizable()
        .frame(width: 22, height: 22)
       .fixedSize(horizontal: true, vertical: true)//這句可以不加
       .aspectRatio(contentMode: .fill)

Button,Picker,Slider,WebView,TextField,ScrollView這些用法和UIKit相似,只是把UI前綴去了

List類似于TableView

GridView:有LazyHGrid,LazyVGrid,相當(dāng)于collectionView

let gridItem = [GridItem(.flexible(),spacing: 0)]

LazyHGrid(rows: gridItem, spacing:0) {
    ForEach(0...10,id:\.self) { index in
        setUpCell()
    }
    
}

Group把控件裝到這個(gè)組里面,可以進(jìn)行一些統(tǒng)一配置

Path劃線,折線虛線都可以,舉一個(gè)虛線的例子:

Path{ path in
    path.move(to: CGPoint(x: 0, y: 100))
    path.addLine(to: CGPoint(x: 200, y: 100))
}
.stroke(Color(white: 1, opacity: 0.2),style: StrokeStyle(lineWidth: 1, lineCap: .round, lineJoin:.round,  dash: [1,2], dashPhase: 0))

屬性裝飾器

理解 SwiftUI 里的屬性裝飾器
@State 屬性變化,刷新UI。用于一個(gè)對(duì)象內(nèi)屬性修飾
@StateObject 用于生成和管理狀態(tài)屬性的生命周期
@ObservedObject 修飾共享狀態(tài)從外部傳遞進(jìn)來的屬性,修飾的屬性要實(shí)現(xiàn)ObservableObject協(xié)議
ObservableObject協(xié)議,對(duì)應(yīng)屬性內(nèi)要實(shí)現(xiàn)

var age = 100 {
        willSet {
            objectWillChange.send()
        }
   }

簡(jiǎn)寫是用@Published修飾@Published var age = 100
需要注意的是多層監(jiān)聽屬性傳遞都要用@ObservedObject修飾,所以有了@EnvironmentObject

@EnvironmentObject 修飾全局,避免多個(gè)對(duì)象傳遞用@ObservedObject修飾

ParentView()
      .environmentObject(user)

 struct ParentView : View{
        var body: some View {
            ChindView()
        }
  }

 struct ChindView : View {
        @EnvironmentObject var user : UserModel
}

@Binding 修飾的屬性變?yōu)橐脗鬟f

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 前言 SwiftUI出來也有段時(shí)間了,關(guān)于SwiftUI更多的信息請(qǐng)看這里,那么蘋果為什么要推出SwiftUI呢?...
    Codepgq閱讀 10,436評(píng)論 3 18
  • SwiftUI要求 iOS13.0+ 快捷鍵 control + option + 點(diǎn)擊:出現(xiàn)屬性編輯器 comm...
    余青松閱讀 6,773評(píng)論 1 11
  • 這是 WWDC2019 發(fā)布的 SwiftUI 布局框架的一些官方示例。 首先為了保證項(xiàng)目的正常運(yùn)行,需要升級(jí) M...
    揚(yáng)仔360閱讀 7,641評(píng)論 2 8
  • 最前面想說的話 轉(zhuǎn)眼已經(jīng)是2020年10月了,2020已經(jīng)過去大半了,上半年的計(jì)劃已經(jīng)完成,所以下半年的學(xué)習(xí)應(yīng)該提...
    微笑_d797閱讀 2,997評(píng)論 2 2
  • 文章內(nèi)容源處:https://juejin.im/post/5cf5f4596fb9a07ede0b2fa1#he...
    LINGSHOW閱讀 5,191評(píng)論 1 4

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