SwiftUI-State和Binding

宋明    |     2023/03/18 posted in    SwiftUI

@State

@State private var isPlaying = false
在前面的文章我已用过@State属性,使用@State修饰某个属性后,SwiftUI将会把该属性存储到一个特殊的内存区域内,并且这个区域和View struct是隔离的;
当@State修饰的属性的值发生变化后,SwiftUI会根据该属性重新绘制视图;
举个例子:

struct ContentView: View {
   @State var buttonTaped = false
    
    var body: some View {
        
        VStack{
            Button {
                self.buttonTaped.toggle()
                
            } label: {
                  Text(buttonTaped  ?  "你好" : "Hello World")
            }
            Button {
                self.buttonTaped.toggle()
                
            } label: {
                  Text(buttonTaped  ?  "你好" : "Hello World")
            }
            Button {
                self.buttonTaped.toggle()
                
            } label: {
                  Text(buttonTaped  ?  "你好" : "Hello World")
            }
            Button {
                self.buttonTaped.toggle()
                
            } label: {
                  Text(buttonTaped  ?  "你好" : "Hello World")
            }
        }
        //渲染颜色
        .tint(.purple)
        // 按钮样式 .bordered、.borderless 和 .plain
        .buttonStyle(.bordered)
        //按钮边框样式
        .buttonBorderShape(.capsule)
        //按钮预设大小
        .controlSize(.large)
        
        
    }
}

实现效果 当我们点击时 按钮的文字会自动变化 不需要手动设置数据刷新UI
2023-03-03_13-28-59 (1).gif

@Binding

开发中,我们需要把一个View的属性,传递到一个子View中;
Swift中,值传递的形式是值传递,也就是说,传个子View的是值的拷贝;子视图对这个值进行了修改后,不会影响父视图;
使用@Binding修饰后,属性就变成了一个引用类型,这样子视图对值进行了修改后,父视图中的值也会发生变化

struct customButton:View {
    @Binding var tapCount:Int
    var body: some View {
        Button {
            self.tapCount += 1
            
        } label: {
            Text("Hello World 第\(tapCount)次点击")
        }    //渲染颜色
        .tint(.purple)
        // 按钮样式 .bordered、.borderless 和 .plain
        .buttonStyle(.bordered)
        //按钮边框样式
        .buttonBorderShape(.capsule)
        //按钮预设大小
        .controlSize(.large)
    }
}


struct ContentView: View {
 
    @State private var tapCount = 0
    
    var body: some View {
        
        VStack{
            customButton(tapCount: $tapCount)
        }
    
        
    }
}

如果有多个按钮需要分别管理 还是推荐@State

给每个按钮绑定自己的tapCount 属性

struct customButton:View {
  @State var tapCount:Int = 0
    var body: some View {
        Button {
            self.tapCount += 1
            
        } label: {
            Text("Hello World 第\(tapCount)次点击")
        }    //渲染颜色
        .tint(.purple)
        // 按钮样式 .bordered、.borderless 和 .plain
        .buttonStyle(.bordered)
        //按钮边框样式
        .buttonBorderShape(.capsule)
        //按钮预设大小
        .controlSize(.large)
    }
}


struct ContentView: View {
 
  
    var body: some View {
        
        VStack{
            customButton()
            customButton()
            customButton()
        }
    
        
    }
}