https://www.bilibili.com/video/BV1q64y1d7x5?p=2
PreviewProvider
中定义的组件,可以在预览框实时预览。
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().preferredColorScheme(.light)
ContentView().preferredColorScheme(.dark)
}
}
我们可以用一个新的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...
var count = 3 //定义一个变量
var body: some View {
HStack{
//使用变量
ForEach(emojis[0..<count],id: \.self){ emoji in
MyCardView(emoji: emoji)
}
}
}
Button(action: {
//此处编写逻辑
}, label: {
//ViewBuilder
})
可以省略action
Button{
//逻辑
} label: {
//ViewBuilder
}
或者逻辑与视图分离
func myFunction(){
//此处编写逻辑
}
Button(action: myFunction) {
//ViewBuilder
}
ScrollView
、LazyVGrid
与.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)
}