为 Swift UI 视图创建自定义修饰符
Creating custom modifiers for Swift UI views
想知道如何为 Swift UI 视图创建修饰符?
例如,假设我有一些定义如下的视图:
struct LabelView: View {
let font1: Font = .header
let font2: Font = .body
var body: Some View {
// two views, where one uses font1 and other uses font2
}
}
如何创建一个修饰符来允许类似的东西:
LabelView()
.font1(.callout)
.font2(.body)
我正在尝试学习如何以声明性方式编写 API,Apple 正在推动 Swift UI,但文档似乎不完整这个。我试过创建某种 ViewModifier
类型,但我不太确定我需要用它做什么,因为它需要我 return _ModifiedContent<_, _>
并且不确定该怎么做这个。基本上,是否可以使用声明性语法修改视图的属性,例如内置 SwiftUI 视图中的语法。
正如评论中链接到的 dfd,您可以创建使用苹果提供的修饰符的自定义修饰符。不过,您可以也 创建自己的方法来修改 var
s。
注意:您不能在此处使用可变方法,因为函数构建器 return 不可变值。你会得到一个编译器错误。您需要制作 self
和 return 的副本。
extension LabelView {
func font1(_ font1: Font) -> Self {
var copy = self
copy.font1 = font1
return copy
}
}
您还可以创建一个使用键路径更新变量的通用版本:
extension View {
func modifying<T>(_ keyPath: WritableKeyPath<Self, T>, value: T) -> Self {
var copy = self
copy[keyPath: keyPath] = value
return copy
}
}
两个版本的用法:
struct LabelView: View {
var font1: Font = .headline
var font2: Font = .body
var body: some View { ... }
}
LabelView()
.modifying(\.font2, value: .callout)
.font1(.largeTitle)
结果如下:
看看这是否是您想要的。您可以根据需要简单地修改属性。如果你想要一个固定的textView,那么在自定义labelView中保持静态。
import SwiftUI
struct LabelView: View {
var font1: Font = .headline
var font2: Font = .subheadline
var text1: String = ""
var text2: String = ""
var body: some View {
VStack {
Text(text1).lineLimit(nil).font(font1)
Text(text2).lineLimit(nil).font(font2)
}
}
}
struct Whosebug : View {
var body: some View {
//LabelView(font1: .title, font2: .subheadline )
LabelView(font1: .title, font2: .subheadline, text1: "What is Lorem Ipsum?", text2: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.")
}
}
想知道如何为 Swift UI 视图创建修饰符?
例如,假设我有一些定义如下的视图:
struct LabelView: View {
let font1: Font = .header
let font2: Font = .body
var body: Some View {
// two views, where one uses font1 and other uses font2
}
}
如何创建一个修饰符来允许类似的东西:
LabelView()
.font1(.callout)
.font2(.body)
我正在尝试学习如何以声明性方式编写 API,Apple 正在推动 Swift UI,但文档似乎不完整这个。我试过创建某种 ViewModifier
类型,但我不太确定我需要用它做什么,因为它需要我 return _ModifiedContent<_, _>
并且不确定该怎么做这个。基本上,是否可以使用声明性语法修改视图的属性,例如内置 SwiftUI 视图中的语法。
正如评论中链接到的 dfd,您可以创建使用苹果提供的修饰符的自定义修饰符。不过,您可以也 创建自己的方法来修改 var
s。
注意:您不能在此处使用可变方法,因为函数构建器 return 不可变值。你会得到一个编译器错误。您需要制作 self
和 return 的副本。
extension LabelView {
func font1(_ font1: Font) -> Self {
var copy = self
copy.font1 = font1
return copy
}
}
您还可以创建一个使用键路径更新变量的通用版本:
extension View {
func modifying<T>(_ keyPath: WritableKeyPath<Self, T>, value: T) -> Self {
var copy = self
copy[keyPath: keyPath] = value
return copy
}
}
两个版本的用法:
struct LabelView: View {
var font1: Font = .headline
var font2: Font = .body
var body: some View { ... }
}
LabelView()
.modifying(\.font2, value: .callout)
.font1(.largeTitle)
结果如下:
看看这是否是您想要的。您可以根据需要简单地修改属性。如果你想要一个固定的textView,那么在自定义labelView中保持静态。
import SwiftUI
struct LabelView: View {
var font1: Font = .headline
var font2: Font = .subheadline
var text1: String = ""
var text2: String = ""
var body: some View {
VStack {
Text(text1).lineLimit(nil).font(font1)
Text(text2).lineLimit(nil).font(font2)
}
}
}
struct Whosebug : View {
var body: some View {
//LabelView(font1: .title, font2: .subheadline )
LabelView(font1: .title, font2: .subheadline, text1: "What is Lorem Ipsum?", text2: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.")
}
}