SwiftUI 自定义图像修饰符

12

我正在尝试创建一个自定义图像修改器,它使用 resizable() 函数,因此我的 content 应该是一个 Image。至少,这是我所认为的。

错误信息类型 'IconModifier' 不符合协议 'ViewModifier'

struct IconModifier: ViewModifier {
    func body(content: Image) -> some View {
        content
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width: 10, height: 10, alignment: .center)
    }
}
1个回答

27

解决方案

你可以直接扩展Image

使用方法如下:

struct ContentView: View {

    var body: some View {
        VStack {
            Text("Hello World!")
            
            Image("someName")
                .imageIconModifier()
        }
    }
}

Image扩展名:

extension Image {
    
    func imageIconModifier() -> some View {
        self
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width: 10, height: 10, alignment: .center)
    }
}

为什么你的解决方案行不通

首先,你遇到了这个错误:

Type 'IconModifier' does not conform to protocol 'ViewModifier'

这意味着你的 IconModifier 没有满足 ViewModifier 协议的要求,如果我们看一下它的定义:

func body(content: Self.Content) -> Self.Body

而你曾拥有:

func body(content: Image) -> Self.Body

它不起作用。所以下一步 - 我们将把它从Image更改为Content

类型'IconModifier.Content'(也称'_ViewModifier_Content')的值没有成员'resizable'

这基本上是说没有任何View.resizable()修改器。 .resizable()修改器在extension Image内部定义,因此没有其他View具有此修改器。

这就是核心问题 - 无法通过ViewModifier中的content参数访问原始View(对我们而言是Image)。

这就是我为什么只是为Image创建了一个扩展的原因。

希望这个解释有帮助!


谢谢你的回答,但我也想了解一下为什么我的上面的解决方案不起作用。在底层实际发生了什么导致了错误? - Pondorasti
2
@Pondorasti 添加了一份解释,希望能有所帮助 :) - George
好的回答,但它留下了一个大问题。如果无法实现仅适用于图像的ViewModifier,那么.resizable()本身是如何实现的? - dented42
@dented42 内置的修饰符只是 View 的扩展,或者特定类型(在这种情况下是 Image)的扩展。我不知道任何内置的修饰符是一个 ViewModifierViewModifier 是符合 ViewModifier 协议的结构体,因此您可以使用 .modifier(_:) 应用它。 - George
@dented42 那是一个好问题,它让我思考:如果SwiftUI本身不经常使用ViewModifier,那么ViewModifier的意义是什么?这里有一个相关主题的问题。您还可以将其与ModifiedContent一起使用。 - George

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接