如何为形状添加自定义视图修改器

Posted

技术标签:

【中文标题】如何为形状添加自定义视图修改器【英文标题】:How can i add a custom View modifier for Shapes 【发布时间】:2019-11-21 00:15:17 【问题描述】:

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

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

要获得我读到的这种行为,您可以像下面那样扩展视图。它与 String 完美搭配,但我不明白 Shape 有什么不同?

我收到错误消息 Protocol type 'Shape' cannot conform to '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 在我的情况下,如果发现只需对整个 ImageView 进行剪辑整形就可以了。 我还想链接这个Creating custom modifiers for Swift UI views,您可以在其中阅读有关自定义修饰符的信息

【问题讨论】:

【参考方案1】:

我在寻找相同标题但意图不同时发现了这个问题 - 我想创建一个可以专门应用于符合 Shape 的东西的修饰符,以便我可以用它做类似 Shape 的效果 - 笔画等。

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

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

基本要点是 ViewModifier 总是与 View 上的方法一起工作,其中 ViewBuilder 被用作组合视图的一种方式,这听起来更像你想要的。最后,它们在可以做的事情上有很大的重叠——主要是在实现它的方式上有所不同。

【讨论】:

【参考方案2】:

这是一个 3 步过程:

    创建一个ViewModifier 使用函数扩展 View 以应用修改器并返回修改后的视图 在实际的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()
  

【讨论】:

你做的和我做的不一样。我想将修改器应用于整个视图,然后定位其中的图像。您只需将其直接放在 Text 上即可。正如我所说,我的代码适用于字符串,但不适用于 Shape 协议 修饰符以它们附加到的视图为目标。视图协议指定 body 是一些视图,这意味着类型是不透明的,您不能访问它的内部成员。您仍然可以将剪辑定位到封闭视图。 这并没有真正帮助我,但我想出了一些办法。我在问题中进行了编辑。还是谢谢!

以上是关于如何为形状添加自定义视图修改器的主要内容,如果未能解决你的问题,请参考以下文章

如何为自定义表格视图单元格中的按钮单击获取不同的视图控制器

如何为列表视图创建自定义光标适配器以用于图像和文本?

如何为新式体验文档库自定义 SharePoint Online 列/字段?

如何为 UITableView 添加自定义 EditingAccessoryView?

如何为列表视图创建自定义适配器?获取 ResourceNotFoundException

如何为自定义视图选择设置膨胀和颜色变化的动画?