首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ViewModifier中创建SwiftUI与视图扩展的区别

在ViewModifier中创建SwiftUI与视图扩展的区别
EN

Stack Overflow用户
提问于 2019-08-08 11:36:15
回答 5查看 8.6K关注 0票数 46

我试图找出这两种方法之间的实际区别。例如:

代码语言:javascript
复制
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)
    }
}

然后,我们可以使用所有这些方法如下:

代码语言:javascript
复制
Text(tech.title)
    .modifier(PrimaryLabel())
Text(tech.title)
    .makePrimaryLabel()
ModifiedContent(
    content: Text(tech.title),
    modifier: PrimaryLabel()
)
EN

回答 5

Stack Overflow用户

发布于 2019-08-08 11:53:56

你提到的所有方法都是正确的。区别在于您如何使用它,以及您在何处访问它。哪个更好?是一个意见基础问题,您应该看看干净的代码、策略和坚实的原则等等,以找到每个案例的最佳实践。

由于SwiftUI是非常修饰符链基,所以第二个选项是最接近原始修饰符的。你也可以拿正本这样的论点:

代码语言:javascript
复制
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")
            }
        }
    }
}

我们应该拭目以待,看看这种新技术中的最佳实践是什么。我们现在发现的任何东西都只是良好的实践。

票数 22
EN

Stack Overflow用户

发布于 2019-08-08 12:43:46

我通常更喜欢扩展,因为它们为您提供了更易读的代码,而且它们通常编写的时间更短。我写了文章关于View扩展的文章。

但是,也有不同之处。至少有一个。使用ViewModifier,您可以拥有@State变量,但不能使用视图扩展。下面是一个例子:

代码语言:javascript
复制
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()
        }
    }
}
票数 20
EN

Stack Overflow用户

发布于 2021-08-19 16:01:23

我认为最好的方法是将ViewModifiers和视图扩展结合起来。这将允许在ViewModifier中合成@State并方便视图扩展。

代码语言:javascript
复制
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 {
        ModifiedContent(content: self, modifier: PrimaryLabel())
    }
}

使用

代码语言:javascript
复制
Text(tech.title)
    .makePrimaryLabel()
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57411656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档