SwiftUI 2.0 课程笔记 Chapter 2

课程链接:https://www.bilibili.com/video/BV1q64y1d7x5?p=2

课程项目仓库:https://github.com/cnatom/MemorizeSwiftUI

同时预览明亮和暗黑模式

PreviewProvider中定义的组件,可以在预览框实时预览。

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().preferredColorScheme(.light)
        ContentView().preferredColorScheme(.dark)
    }
}

自定义View

我们可以用一个新的struct来自定义View

struct ContentView: View {
    var body: some View {
        HStack{
            MyCardView(hide: false) // 调用组件并覆盖hide变量默认值
            MyCardView(hide: false)
            MyCardView() //调用组件
            MyCardView()

        }
    }
}
//定义组件 MyCardView
struct MyCardView: View{
    var hide: Bool = true
    // 也可以用这种方式定义:var hide: Bool { return true }
    var body: some View{
        ZStack{
            RoundedRectangle(cornerRadius: 25).stroke()
            Text("🍒")
            if hide {
              	// 当hide==true,该组件才会显示
                RoundedRectangle(cornerRadius: 25).fill().foregroundColor(.blue)
            }
        }
    }
}

还可以将View保存在变量或常量中,以简化代码

struct MyCardView: View{
    var hide: Bool = true
    var body: some View{
      	//定义一个View常量
        let shape = RoundedRectangle(cornerRadius: 25)
      	//也可以使用变量 var shape = RoundedRectangle(cornerRadius: 25)
        ZStack{
            shape.stroke() //在这里调用
            Text("🍒")
            if hide {
                shape.fill().foregroundColor(.blue) //在这里调用
            }
        }
    }
  	//  ViewBuilder类型的变量还可以存储多个组件
  	//	var texts: some View{
    //	    Text("hello")
    //  	  Text("swift")
    //	}
  	
}

var全称variable,意为“可变的”

Swift会根据等号右边的类型自动判断变量类型,因此下面两种写法效果是相同的

let shape = RoundedRectangle(cornerRadius: 25)
let shape: RoundedRectangle = RoundedRectangle(cornerRadius: 25)

添加点击事件

使用.onTapGesture修饰器为组件添加点击事件。点击函数内被改变的变量要用@State修饰。

有关@State:https://juejin.cn/post/6976448420722507784

struct MyCardView: View{
    //hide在点击后会改变,因此添加@State修饰
    @State var hide: Bool = true
    var body: some View{
        let shape = RoundedRectangle(cornerRadius: 25)
        ZStack{
            shape.stroke()
            Text("🍒")
            if hide {
                shape.fill().foregroundColor(.blue)
            }
          //添加点击事件
        }.onTapGesture {
            hide = !hide
        }
    }
}

循环创建组件

我们可以使用Foreach循环创建组件,要特别注意其中的一个属性:id,该属性可以用来区分数组的成员,这样可以更有效率地管理 列表 里的视图。

有关Foreach:https://juejin.cn/post/6984753286058344456

struct ContentView: View {
    var emojis = ["🍎","🍎","🍇","🍉","🍌"]
    var body: some View {
        HStack{
            ForEach(emojis,id: \.self, content: { emoji in
                MyCardView(emoji: emoji)
            })
          //content的内容同样可以写在外面
             ForEach(emojis,id: \.self){ emoji in
                MyCardView(emoji: emoji)
            }
        }
    }
}

还可以使用emojis[0...<3]的方式对列表进行切片,表示[0,3)emojis[0...3]则表示[0,3]

ForEach(emojis[0...<3],id: \.self){ emoji in
    MyCardView(emoji: emoji)
}

或者使用变量emojis[0...<count]

var count = 3  //定义一个变量
var body: some View {
    HStack{
      	//使用变量
        ForEach(emojis[0..<count],id: \.self){ emoji in
            MyCardView(emoji: emoji)
        }
    }
}

添加按钮Button

Button(action: {
  //此处编写逻辑
}, label: {
  //ViewBuilder
})

可以省略action

Button{
  //逻辑
} label: {
  //ViewBuilder
}

或者逻辑与视图分离

func myFunction(){
    //此处编写逻辑
}
Button(action: myFunction) {
    //ViewBuilder
}

补充组件

ScrollViewLazyVGrid.aspectRatio()

ScrollView {
    LazyVGrid(columns:[GridItem(.adaptive(minimum: 100, maximum: 100))]){
        ForEach(emojis[0..<count],id: \.self){ emoji in
            MyCardView(emoji: emoji).aspectRatio(2/3,contentMode: .fit)
        }
    }.foregroundColor(.blue)
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值