如何用SwiftUI构建表单—一个全面的指南

595 阅读6分钟

近年来,开发工具最重要的进展之一是SwiftUI的到来,允许开发者使用声明性代码设计和构建用户界面。

SwiftUI目前只支持iOS 13和更新的版本。本教程需要Xcode 11(或更高版本),我们将全程使用Swift 5。

在这篇文章中,我们将一起在SwiftUI中构建一个表单,所以请随时按照自己的节奏来学习本教程--让我们不浪费时间,开始吧!

SwiftUI简介

SwiftUI是苹果生态系统中的一个创新转变。通过相同复杂度的声明性代码来构建应用程序--用更少的代码,使开发者能够在iOS中快速开发应用程序。由于UI模式更加简单和快速,当你使用SwiftUI时,它立即采用了动态类型、黑暗模式、本地化和可访问性等功能。

SwiftUI可以在所有平台上使用,包括macOS、iOS、iPadOS、watchOS和tvOS。由于使用SwiftUI节省了时间,开发者可以花更多时间有效地编写代码,制作特定平台的功能,专注于用户界面,总之,根据我的经验,它是一个非常有用的工具

此外,苹果的生态系统允许你在使用SwiftUI和UIKit的同时使用它们。这对所有的iOS开发者来说是一个很大的优势,使其更容易适应新的转变。

用SwiftUI设置一个Xcode项目

首先,打开Xcode并从菜单中选择创建一个新的Xcode项目

当使用iOS时,选择单视图应用程序。现在是时候命名和描述您的应用程序了。必须在底部选择使用SwiftUI选项。如果你不点击这个选项,Xcode将为你创建故事板文件。

现在,Xcode将自动创建一个名为ContentView.swift 的文件,它将在右侧显示你的代码的实时预览,如下图所示。如果你还没有看到预览,只需点击预览窗格内的恢复按钮,一旦项目被建立,你就可以看到预览了。

有了新的即时预览功能,你可以输入代码并实时看到视觉变化,使整个编程体验更快,并允许你看到发生的改动。

为了使用SwiftUI构建一个表单,我们将开发不同的UI元素。让我们逐一实现它们,更好地了解它们。

创建文本字段

让我们从使用文本标签和文本字段的一个简单实现开始:

// swift
Text("Name").font(.headline)

上面的一行使用Text 组件创建了一个标签,并将该标签的值设置为Name 。此外,.font 属性将其字体类型设置为headline 。要创建一个带有占位符的文本字段,你需要这样编写代码:

// swift
TextField(.constant(""), placeholder: Text("Enter your name"))

你需要告诉SwiftUI框架使用VStack ,并根据需要安排这两个组件,以便将标签放在文本字段上方。下面的代码片断显示了如何做到这一点:

// swift
struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {

            Text("Name").font(.headline)
            TextField(.constant(""), placeholder: Text("Enter your name"))

        }
    }
}

现在我们已经创建了基本的文本字段和标签,让我们改进一下外观和感觉:

// swift
struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("Name").font(.headline)
            TextField(.constant(""), placeholder: Text("Enter your name"))
                .padding(.all)
                .background(Color(red: 200.0/255.0, green: 200.0/255.0, blue: 200.0/255.0, opacity: 0.7), cornerRadius: 8.0)
        }
    }
}

在上面的代码中,我们添加了一个.padding(.all) 属性,它为文本输入框内输入的文本提供填充。此外,.background 属性允许你定义文本输入字段的背景颜色,并设置了一个cornerRadius ,在这个例子中是8.0

接下来,让我们固定与屏幕边缘的间距。要做到这一点,你需要将.padding 属性指定给VStack, ,该属性将元素置于自身之内:

// swift
struct ContentView : View {

    @State var name: String = ""

    var body: some View {
        VStack(alignment: .leading) {
        Text("Name").font(.headline)
            TextField(.constant(""), text: $name, placeholder: Text("Enter your name"))
                .padding(.all)
                .background(Color(red: 200.0/255.0, green: 200.0/255.0, blue: 200.0/255.0, opacity: 0.7), cornerRadius: 8.0)
        }
        .padding(.horizontal, 16)
    }
}

(注意:我们还添加了一个名为nameState 变量,以保存文本输入的值)

将组件转换为表单

要填充不同的UI组件和视图,重用它们比重复编写代码更有效率。SwiftUI 中的Form 是一个容器视图,它允许你将用于数据输入的控件分组。

上面提到的组件可以用下面的Form 编码:

// swift
struct ContentView: View {


    @State var name: String = ""

    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Profile")) {
                    Text("Name").font(.headline)
                    TextField(.constant(""), text: $name, placeholder: Text("Enter your name"))
                        .padding(.all)
                        .background(Color(red: 200.0/255.0, green: 200.0/255.0, blue: 200.0/255.0, opacity: 0.7), cornerRadius: 8.0)
                    }
                }
                .padding(.horizontal, 16)
            }
            .navigationBarTitle("Settings")
        }
    }
}

上述代码允许您在NavigationView 内指定Form 对象。Section 允许您在表单视图内创建一个单独的部分,然后您可以使用header 属性对其进行标注。

创建切换器

您已经成功地使用 SwiftUI 创建了表单中的第一个组件让我们通过添加一个Toggle 来更新您的表单,以提供一个选项,使配置文件隐藏起来:

// swift
struct ContentView: View {


    @State var name: String = ""
    @State var isHidden: Bool = false

    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Profile")) {
                    Text("Name").font(.headline)
                    TextField(.constant(""), text: $name, placeholder: Text("Enter your name"))
                        .padding(.all)
                        .background(Color(red: 200.0/255.0, green: 200.0/255.0, blue: 200.0/255.0, opacity: 0.7), cornerRadius: 8.0)
                    }
                    Toggle(isOn: $isHidden) {
                        Text("Hide account")
                    }
                }
                .padding(.horizontal, 16)
            }
            .navigationBarTitle("Settings")
        }
    }
}

Toggle 被添加到TextField 的下面,如代码所示,它允许你打开或关闭它,并将要处理的值保存在名为isHidden 的变量中,你可以根据需要访问和更新业务逻辑。

创建一个选取器

您可以使用 SwiftUIPicker 组件从一个选项列表中选择一个所需的值。为使Picker 正常工作,您必须为其提供一个选项数组和一个记录所选选项的State 变量。让我们创建一个Picker ,使我们能够存储所选择的偏好:

// swift
struct ContentView: View {


    @State var name: String = ""
    @State var isHidden: Bool = false
    @State var email: String = ""
    @State var receiveEmails: Bool = false
    @State private var index = 0
    var emailOptions = ["All", "Transactional", "Marketing"]

    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Profile")) {
                    Text("Name").font(.headline)
                    TextField(.constant(""), text: $name, placeholder: Text("Enter your name"))
                        .padding(.all)
                        .background(Color(red: 200.0/255.0, green: 200.0/255.0, blue: 200.0/255.0, opacity: 0.7), cornerRadius: 8.0)
                    }
                    Toggle(isOn: $isHidden) {
                        Text("Hide account")
                    }
                }
                .padding(.horizontal, 16)


                Section(header: Text("Emails")) {
                    Toggle(isOn: $receiveEmails) {
                        Text("Receive emails")
                    }
                    TextField(.constant(""), text: $email, placeholder: Text("Enter your email"))
                        .padding(.all)
                        .background(Color(red: 200.0/255.0, green: 200.0/255.0, blue: 200.0/255.0, opacity: 0.7), cornerRadius: 8.0)
                    }
                    Picker(selection: $index, label: Text("Email types")) {
                        ForEach(0 ..< emailOptions.count) {
                            Text(self.emailOptions[$0])
                        }
                    }
                }
                .padding(.horizontal, 16)
            }
            .navigationBarTitle("Settings")
        }
    }
}

正如你在代码中看到的,引入了一个名为Emails 的新部分,其中有一个Toggle ,用于启用电子邮件通知,一个TextField ,将电子邮件作为输入,一个Picker ,用于选择电子邮件的类型。

创建一个滑块

Slider 是一个组件,它允许你在一条线上拖动选择,从已经设置好的范围内选择一个值。UIKit中的 ,类似于SwiftUI中的 。UISlider Slider

你可以像这样定义一个滑块:

// swift
struct ContentView: View {


    @State var name: String = ""
    @State var isHidden: Bool = false
    @State var email: String = ""
    @State var receiveEmails: Bool = false
    @State private var index = 0
    var emailOptions = ["All", "Transactional", "Marketing"]
    @State var volumeSliderValue: Double = 0

    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Profile")) {
                    Text("Name").font(.headline)
                    TextField(.constant(""), text: $name, placeholder: Text("Enter your name"))
                        .padding(.all)
                        .background(Color(red: 200.0/255.0, green: 200.0/255.0, blue: 200.0/255.0, opacity: 0.7), cornerRadius: 8.0)
                    }
                    Toggle(isOn: $isHidden) {
                        Text("Hide account")
                    }
                }
                .padding(.horizontal, 16)


                Section(header: Text("Emails")) {
                    Toggle(isOn: $receiveEmails) {
                        Text("Receive emails")
                    }
                    TextField(.constant(""), text: $email, placeholder: Text("Enter your email"))
                        .padding(.all)
                        .background(Color(red: 200.0/255.0, green: 200.0/255.0, blue: 200.0/255.0, opacity: 0.7), cornerRadius: 8.0)
                    }
                    Picker(selection: $index, label: Text("Email types")) {
                        ForEach(0 ..< emailOptions.count) {
                            Text(self.emailOptions[$0])
                        }
                    }
                }
                .padding(.horizontal, 16)

                Section(header: Text("Emails")) {
                    Slider(value: $volumeSliderValue, in: 0...100, step: 1)
                    .padding()
                    .accentColor(Color.blue)
                    .border(Color.blue, width: 3)
                }
                .padding(.horizontal, 16)
            }
            .navigationBarTitle("Settings")
        }
    }
}

在上面的代码中,定义了一个名为volumeSliderValue 的状态变量,它存储了滑块的当前值。Slider 组件是通过传递volumeSliderValue 以及跨越Slider 的可能值的范围而创建的。

你也可以通过在参数中定义step 值来增加Slider'的增量值。此外,你还可以通过修改器accentColor()border() ,分别改变滑块的颜色和周围的边界。

总结

本文展示了SwiftUI的使用,以及如何使用SwiftUI创建一个表单。虽然这篇文章展示了这个概念的基本内容,但SwiftUI提供的内容还有很多。