SwiftUI 学习(六)

271 阅读3分钟

「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战

State

所有的SwiftUI应用都会更改状态。 例如,用户可能点击了一个按钮来显示更多信息,他们可能已经在文本框中输入了一些文本,或者从日期选择器中选择了一个日期——所有这些都涉及到应用程序从一个状态移动到另一个状态。

State的问题在于它很混乱:当它发生变化时,我们需要发现这种变化并更新布局。 起初这听起来很简单,但随着我们的状态不断增长,它变得越来越困难——很容易忘记更新某件事,或者更新顺序错误,从而导致用户界面状态与预期不符。

SwiftUI 通过从我们的控件中移除状态来解决这个问题。 当我们向视图添加属性时,它们实际上是惰性的——它们当然有值,但改变它们并没有任何作用。 但是,如果我们在它们之前添加特殊的 @State 属性,SwiftUI 将自动监视更改并更新使用该状态的视图的任何部分。

When it comes to referring to some state – for example, telling a state property to change when a toggle switch changes – we can’t refer to the property directly. This is because Swift would think we just want to read the value right now rather than saying “please also update this value as things change.” Fortunately, SwiftUI’s solution is to place a dollar sign before the property name, which lets us refer to the underlying data binding rather than its current value. I know this is a little confusing at first, but it becomes second nature after an hour or two.

创建一个可点击的Button

SwiftUI 的按钮与 UIButton 类似,不同之处在于它在显示内容方面更加灵活,并且它的动作使用闭包而不是旧的target/action。

Button("Button title") {
    print("Button tapped!")
}

可以制作一个按钮,在点击时显示或隐藏一些详细文本:

struct ContentView: View {
    @State private var showDetails = false

    var body: some View {
        VStack(alignment: .leading) {
            Button("Show details") {
                showDetails.toggle()
            }

            if showDetails {
                Text("You should follow me on Twitter: @twostraws")
                    .font(.largeTitle)
            }
        }
    }
}

从TextField 读取内容

SwiftUI 的 TextField 视图与 UIKit 中的 UITextField 类似,尽管它在默认情况下看起来有些不同,并且非常依赖于绑定到状态。

要创建一个,您应该传入一个占位符以在文本字段内使用,加上它应该绑定到的状态值。 例如,这会创建一个绑定到本地字符串的 TextField,然后在其下方放置一个文本视图,在您键入时显示文本字段的输出:

struct ContentView: View {
    @State private var name: String = "Tim"

    var body: some View {
        VStack(alignment: .leading) {
            TextField("Enter your name", text: $name)
            Text("Hello, (name)!")
        }
    }
}

SwiftUI 的 TextField 视图默认没有样式,这意味着它在屏幕上是一个空白区域。 如果这符合你想要的风格,那就太好了——你就完成了。 但是我们中的许多人更喜欢在文本字段周围添加边框以使其更清晰。

如果你想获得我们习惯使用 UITextField 的“圆角矩形”文本字段样式,你应该使用 .textFieldStyle(.roundedBorder)) 修饰符,如下所示:

struct ContentView: View {
    @State private var name: String = "Tim"

    var body: some View {
        VStack(alignment: .leading) {
            TextField("Enter your name", text: $name)
                .textFieldStyle(.roundedBorder)
            Text("Hello, (name)!")
        }
    }
}

SwiftUI 的 TextField 支持占位符文本,就像 UITextField 所做的一样——当文本字段为空时显示在文本字段中的灰色文本,或者给用户一个提示(“xxxx”)或者显示一些示例数据。

struct ContentView: View {
    @State private var emailAddress = ""

    var body: some View {
        TextField("johnnyappleseed@apple.com", text: $emailAddress)
            .textFieldStyle(.roundedBorder)
            .padding()
    }
}

SwiftUI 的 TextField 默认启用自动更正,这在大多数情况下是您想要的。 但是,如果要禁用它,可以使用 disableAutocorrection() 修饰符来禁用它,如下所示:

struct ContentView: View {
    @State private var name = ""

    var body: some View {
        TextField("Enter your name", text: $name)
            .disableAutocorrection(true)
    }
}