如何添加形状的自定义视图修饰符

时间:2019-11-21 00:15:17

标签: swift swiftui

我想用某种修饰符调用我的ImageView,以使其中的Image变为圆形或正方形。该代码应如下所示:

ImageView(withURL: newsItem.imageUrl).test(Circle())

要阅读此行为,请阅读您可以像下面所做的那样扩展视图。它可以很好地与String一起工作,但我不知道Shape有什么不同?

我收到错误消息协议类型'Shape'不符合'Shape',因为只有具体类型可以符合协议,但我也不明白:/。有人可以向我解释问题以及我该怎么做吗?

struct ImageView: View {
    var clipShape: Shape

    var body: some View {
        ZStack {
            Image("swift")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .clipShape(self.clipShape)
                .shadow(radius: 6)
        }
    }
}

extension ImageView {
    func test(_ shape: Shape) -> Self {
        var copy = self
        copy.clipShape = shape
        return copy
    }
}

此代码已缩短为仅显示特定问题的代码,视图包含的代码更多。只是为了您不要质疑它的使用。

非常感谢!

编辑:

为什么形状不起作用以及如何处理:https://forums.swift.org/t/how-to-make-different-clipshape/27448/2 在我的案例中,如果发现只是clipShaping整个ImageView就可以了。 我也想链接此Creating custom modifiers for Swift UI views,在这里您可以阅读有关自定义修饰符的信息

2 个答案:

答案 0 :(得分:0)

它分为三个步骤:

  1. 制作一个ViewModifier
  2. 使用功能来扩展View,以应用修改器并返回修改后的视图
  3. 在实际的View上调用您的修改函数
struct RedBackGroundModifier: ViewModifier {
  func body(content: Content) -> some View {
    content.background(Color.red)
  }
}

extension View {
  func makeTheBackGroundRed() -> some View {
    self.modifier(RedBackGroundModifier())
  }
}

struct ContentView: View {
  var body: some View {
    Text("Hello, World!").makeTheBackGroundRed()
  }
}

答案 1 :(得分:0)

我在寻找相同标题但意图不同的时候发现了这个问题-我想创建一个可以专门应用于符合Shape的修饰符,以便我可以用它做Shape效果(笔触等)。< / p>

但是,尽管我还没有找到答案,但是我认为您的答案是ViewModifier无法插入/更改视图的内部值-相反,您应该考虑使用ViewBuilder。

我发现没有多少文章真正地突出了如何以及何时有效地选择使用ViewBuilder,但是Majid的标题为The power of @ViewBuilder in SwiftUI的这篇文章做得很好。 Apple's docs on ViewBuilder还(幸运地)在参考(SwiftUI的少数几个地方之一)中包含了一些示例代码,至少向您展示了如何使用它的一些基本思想。

基本要点在于,ViewModifier通常总是与View上的方法一起使用,其中ViewBuilder用作将组成视图的一种方式,听起来更像是您想要的。最后,他们在工作上有很大的重叠-主要区别在于实现方式。