swift - 将 SwiftUI 视图提取到新视图中
问题描述
有没有办法将配置的视图提取到它自己的视图结构中,以便可以应用某些自定义?例如,我Button
在 UI 的几个地方进行了配置:
Button(action: {}) {
Text("Some Button Text")
.font(.custom("SomeFont", size: 17.0))
.fontWeight(.bold)
}
.frame(maxWidth: .infinity)
.frame(height: 50.0)
.foregroundColor(.black)
.background(Color("user-profile-action-call1"))
.clipShape(RoundedRectangle(cornerSize: CGSize(width: 10.0, height: 10.0)))
.padding([.leading, .trailing], 20.0)
.padding(.top, 33.0)
我希望能够重新使用它,指定不同的按钮文本和不同的背景颜色。显然,一种方法是创建一个新View
的,将 aString
和Color
作为参数/属性,并像这样使用它:
MyButton(title: "Some Button Text", color: Color("user-profile-action-call1"))
但这与 SwiftUI 不一致:
MyButton(title: "Some Button Text")
.background(Color("user-profile-action-call1"))
不幸的是,将背景放在填充区域之后.clipShape()
会导致填充区域,而不是剪切区域。
有时我也想改变其他方面。但我不确定如何制作像这样的真正自定义视图。
解决方案
Grey 的答案是将修饰符组合成自定义修饰符的一个很好的答案,但我认为更惯用的 SwiftUI 方式是创建按钮样式。
自定义按钮样式是符合ButtonStyle
协议的结构;为了满足协议要求,您需要提供一个makeBody
将您的样式应用于按钮并返回新视图的函数。像任何其他视图或修饰符一样,您可以声明变量来初始化您的结构,以使样式可自定义。
在您的情况下,我将提取除填充值之外的所有内容:
struct FullWidthButtonStyle: ButtonStyle {
var backgroundColor: Color
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.custom("SomeFont", size: 17.0).bold())
.frame(maxWidth: .infinity)
.frame(height: 50.0)
.foregroundColor(.black)
.background(backgroundColor)
.clipShape(RoundedRectangle(cornerSize: CGSize(width: 10.0, height: 10.0)))
}
}
请注意,因为我们将字体应用于 aButton
而不是直接应用于Text
,所以.fontWeight
修饰符将不起作用 - 但我们应该能够应用于.bold()
字体声明本身(这需要 Xcode 12.5 - 在早期版本中,您需要切换能够Font.custom...
以这种方式链接字体修饰符)。
然后,您可以将样式应用于任何按钮,指定您喜欢的任何背景颜色:
Button(action: {}) { Text("Some Button Text") }
.buttonStyle(FullWidthButtonStyle(backgroundColor: Color("user-profile-action-call1"))
Button(action: {}) { Text("Some other button text") }
.buttonStyle(FullWidthButtonStyle(backgroundColor: .orange))
当谈到 ViewModifier 与 ButtonStyle 时,我认为后者给了您一点额外的语义优势:您只想将此样式应用于按钮而不是其他任何东西,但是视图修饰符有点过于笼统,无法传达这一点。
推荐阅读
- python - 正则表达式澄清?
- javascript - 康威的生命游戏——滑翔机不动
- xcode - Bash - 通过对话框确认卸载应用程序
- python - 在 Python shell 中使用 " 引号而不是 ' 打印
- angular - 根据 url 动态更改内容 - angular 4
- functional-programming - 大类型上的模式匹配,一种减少代码大小的方法
- powershell - 使用 powershell 删除 .csv 文件中的最后一行
- docker - docker内的Spring Shell应用程序
- bash - bash:如何按名称字母排序或解析数组[id][name]以注入whiptail?
- php - 我必须替换 php 中定义的块或占位符位置并复制到另一个文件