我正在尝试找出这两种方法之间的实际区别。例如:
struct PrimaryLabel: ViewModifier {
func body(content: Content) -> some View {
content
.padding()
.background(Color.black)
.foregroundColor(Color.white)
.font(.largeTitle)
.cornerRadius(10)
}
}
extension View {
func makePrimaryLabel() -> some View {
self
.padding()
.background(Color.black)
.foregroundColor(Color.white)
.font(.largeTitle)
.cornerRadius(10)
}
}
然后我们可以通过以下方式使用所有这些对象:
Text(tech.title)
.modifier(PrimaryLabel())
Text(tech.title)
.makePrimaryLabel()
ModifiedContent(
content: Text(tech.title),
modifier: PrimaryLabel()
)
答案 0 :(得分:4)
您提到的所有方法都是正确的。区别在于您如何使用它以及在何处访问它。 哪个更好?是一个基于意见的问题,您应该查看简洁的代码策略和SOLID原则等,以找到每种情况的最佳实践。
由于SwiftUI
是非常修饰符链的基础,因此第二个选项最接近原始修饰符。您也可以接受诸如原始文件这样的参数:
extension Text {
enum Kind {
case primary
case secondary
}
func style(_ kind: Kind) -> some View {
switch kind {
case .primary:
return self
.padding()
.background(Color.black)
.foregroundColor(Color.white)
.font(.largeTitle)
.cornerRadius(10)
case .secondary:
return self
.padding()
.background(Color.blue)
.foregroundColor(Color.red)
.font(.largeTitle)
.cornerRadius(20)
}
}
}
struct ContentView: View {
@State var kind = Text.Kind.primary
var body: some View {
VStack {
Text("Primary")
.style(kind)
Button(action: {
self.kind = .secondary
}) {
Text("Change me to secondary")
}
}
}
}
我们应该拭目以待,看看像这样的新技术中的最佳实践是什么。我们现在发现的一切只是一种良好的做法。
答案 1 :(得分:4)
我通常更喜欢扩展,因为它们使您的代码更具可读性,并且编写起来通常更短。 事实上,我目前正在撰写具有一些技巧的文章。我写了一篇有关here提供的有关View扩展的文章。
但是,有区别。最后一个。使用ViewModifier,您可以使用@State变量,但不能使用View扩展名。这是一个示例:
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, how are you?").modifier(ColorChangeOnTap())
}
}
}
struct ColorChangeOnTap: ViewModifier {
@State private var tapped: Bool = false
func body(content: Content) -> some View {
return content.foregroundColor(tapped ? .red : .blue).onTapGesture {
self.tapped.toggle()
}
}
}