在iOS 15 中为SwiftUI 按钮设置样式的方法详解

在iOS 15 中,Apple 引入了一个新方法,来为SwiftUI 和UIKit 框架的iOS App 客制化按钮。这篇教学文章主要会介绍SwiftUI 的新功能,如果你有兴趣了解如何在iOS 15 中设置 UIButton 样式,可以参考Sarun 撰写的这篇文章

在SwiftUI 设置按钮样式

在我们介绍iOS 15 的新修饰符(modifier) 之前,先重温一下现在我们设置按钮样式的方法。

swiftui-button-in-ios-15

比如说,我们想创建一个圆角按钮,就可以如此编写程式码:

Button(action: {}) {
    Text("Buy me a coffee")
}
.padding()
.foregroundColor(.white)
.background(Color.purple)
.clipShape(RoundedRectangle(cornerRadius: 5))

我们利用 .clipShape 修饰符,来客制化按钮的前景和背景颜色、应用间距(padding) 和圆角。

在iOS 15 中,要创建一个类似的圆角按钮,我们可以使用新修饰符buttonBorderShape,并应用 BorderedProminentButtonStyle 新样式:

Button(action: {}) {
    Text("Buy me a coffee")
}
.tint(.purple)
.buttonStyle(.borderedProminent)
.buttonBorderShape(.roundedRectangle(radius: 5))
.controlSize(.large)

应用 .borderedProminent 样式后,iOS 就会将按钮呈现为紫色背景和白色文字。.buttonBorderShape则是让我们设置按钮的边框形状(border shape),在这里,我们会设置为.roundedRectangle,以创建圆角按钮。

控制按钮的大小

我们可以利用 .controlSize 来改变按钮的大小。按钮的预设大小是.regular,其他可选的设定包括.large.small、和.mini。让我们看看不同大小的按钮:

swiftui-buttons-control-size

按钮的边框形状

除了 .roundedRectangle 外,SwiftUI 还提供了另外一个边框形状.capsule,让开发者可以创建胶囊形状的按钮。

swiftui-button-border-shape

我们也可以使用.automatic,让系统自动调整按钮的形状。

改变按钮样式

之前我们一直在使用 .borderProminent 按钮样式。新版本的SwiftUI 提供了其他内置样式,包括.bordered.borderless.plain.bordered样式是我们通常会使用的样式。以下是在浅色(light) 和深色模式(dark mode) 下,使用 .bordered 样式的按钮预览图片:

swiftui-button-style

当然,我们还是可以自己编写程式码来创建同样的按钮,但这个iOS 15 的新样式就可以为我们节省不少编写程式码的时间。

把样式应用到多个按钮

设定好按钮样式之后,我们就可以简单地为一组按钮应用同一样式,看看以下例子:

VStack {
    Button(action: {}) {
        Text("Add to Cart")
            .font(.headline)
    }

    Button(action: {}) {
        Text("Discover")
            .font(.headline)
            .frame(maxWidth: 300)
    }

    Button(action: {}) {
        Text("Check out")
            .font(.headline)
    }
}
.tint(.purple)
.buttonStyle(.bordered)
.controlSize(.large)

利用按钮Role

SwiftUI 框架的iOS 15 版本为 Button 引入了一个新的 role 选项。这个选项会描述按钮的Semantic Role。iOS 会根据指定的role,自动为按钮呈现适当的外观。

比如说,我们把role 定义为.destructive

Button("Delete", role: .destructive) {
    print("Delete")
}
.buttonStyle(.borderedProminent)
.controlSize(.large)

iOS 就会自动以红色显示Delete按钮。让我们看看不同role 和样式的配搭,会创建出怎样的按钮外观:

swiftui-button-role

确认对话框(Confirmation Dialog)

iOS 15 除了新的按钮样式之外,还有一个新修饰符.confirmationDialog,我们可以将其附加到 Button 来显示一个确认对话框。

让我们看看显示确认对话框的范例程式码:

struct DemoView: View {
    @State private var isShowingDialog = false
    var body: some View {
        Button("Delete", role: .destructive) {
            isShowingDialog = true
        }
        .buttonStyle(.borderedProminent)
        .controlSize(.large)
        .confirmationDialog("Are you sure to delete the data?", isPresented: $isShowingDialog, titleVisibility: .visible) {

            Button("Confirm", role: .destructive) {
                // Handle the delete action.
            }
            Button("Cancel", role: .cancel) {

            }
        }
    }
}

我们可以在 .confirmationDialog 修饰符设定标题和布林值,用来决定是否显示对话框。你也可以在 titleVisibility 选择是否显示标题。

编写好上述的程式码后,我们会得到以下的确认对话框:

swiftui-confirmation-dialog

利用Material 客制化按钮

在iOS 15 中,SwiftUI 引入了一个Material 型别,让开发者可以创建不同的模糊效果(blur effect)。我们可以在.background 修饰符添加以下的Material,在一个视图后面的视图上应用模糊效果。

  • .ultraThickMaterial
  • .thickMaterial
  • .regularMaterial
  • .thinMaterial
  • .ultraThinMaterial

让我们看看应用了 .ultraThinMaterial 的范例程式码:

Button(action: {}) {
    Text("Add to Cart")
        .font(.headline)
}
.padding()
.background(.ultraThinMaterial, in: Capsule())

就如Apple 所说,添加Material 就像是在视图与其背景之间插入一个半透明层(translucent layer)。如果我们使用不同的Material,就会实作出不同的模糊效果。你可以参考下图,看看不同Material 实作出的模糊效果。

swiftui-background-material

Toggle 按钮

swiftui-toggle

在iOS 中,Toggle 就像是一个开关按钮。在iOS 15 中,我们可以使用 .toggleStyle 修饰符,将Toggle 设置显示为一个按钮:

struct DemoView: View {
    @State private var isEnabled = false

    var body: some View {

        Toggle(isOn: $isEnabled) {
            Label("Airplane mode", systemImage: "airplane.circle.fill")
        }
        .padding()
        .tint(.purple)
        .controlSize(.large)
        .toggleStyle(.button)
    }
}

把 .toggleStyle 设置为 .button 后,Toggle 就会变成按钮的模样。以下是Toggle 在ON/OFF 状态时的外观:

swiftui-toggle-button-ios-15

总结

iOS 15 为客制化SwiftUI 按钮带来了许多改进。虽然我们也可以创建自己的方法来设计按钮样式,但新版本的SwiftUI 有很多内置样式,减轻了开发者的工作。

这些新功能唯一的缺点,就是只支持iOS 15。如果你的App 需要兼容旧版本的iOS,就需要自己实作来设置按钮样式。

庄朋龙
庄朋龙

一个爱生活的技术菜鸟

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注