SwiftUI:ViewModifier,其中内容是图像

时间:2019-11-11 15:57:44

标签: swift swiftui swift-protocols

我收到一个错误“ Type 'PlayButtonModifier' does not conform to protocol 'ViewModifier'”,但我不明白为什么以及-更重要的是-如何正确执行操作。

我只是尝试为ViewModifier创建一个Image,以便可以在其上使用例如.resizable(),它仅在Image

ViewModifier协议中,为Typealias定义了一个Content。我幼稚的想法是,这应该起作用:

struct PlayButtonModifier: ViewModifier {
    typealias Content = Image

    func body(content: Content) -> some View {
        content
    }
}

嗯,不。太容易了。对于隐式结构别名,也会发生同样的事情:

struct PlayButtonModifier: ViewModifier {
    func body(content: Image) -> some View {
        content
    }
}

相同的错误。

这是怎么了?怎么会正确?

2 个答案:

答案 0 :(得分:9)

在这种情况下,修改是特定于特定视图类型的,bucket.upload(file.path, { public: true, destination: set_user_folder + file.name, resumable: true, }, function (err, file, apiResponse) { if (err) { return res.status(200).send({ message: err, type: "error" }); } else { console.log(apiResponse); return res.status(200).send({ message: "File Uploaded", type: "success" }); } }); 说,您可以直接在该视图类型上添加扩展名:

Image

下面是完整的操场文本示例。如果您在操场的“ Resources”文件夹中添加名为“ Otter.png”的可爱水獭图片,则会得到更漂亮的结果:)

extension Image {
    func myImageModifier() -> some View {
        self
            .resizable()
            .aspectRatio(1.0, contentMode: .fit)
            .clipShape(Circle())
   }
}

答案 1 :(得分:0)

感谢Asperi的评论和讨论,我最终使用了以下代码片段。基本上,它是ViewModifier的实现,专门用于图像。

protocol ImageModifier {
    /// `Body` is derived from `View`
    associatedtype Body : View

    /// Modify an image by applying any modifications into `some View`
    func body(image: Image) -> Self.Body
}

extension Image {
    func modifier<M>(_ modifier: M) -> some View where M: ImageModifier {
        modifier.body(image: self)
    }
}

使用很简单:

struct MyImageModifier: ImageModifier {
    func body(image: Image) -> some View {
        image.resizable().scaledToFit()
    }
}

struct MyView: View {
    var body: some View {
        Image(systemName: "play").modifier(MyImageModifier())
    }
}

我不是100%满意,因为必须定义修饰符以返回some View或返回Image。这两种情况都有缺点,并且不能与SwiftUI完美集成。

在定义ImageModifier以返回Image时,它减少了将图像修改为仅针对图像的修饰符(实际上为resizable())的可能性,并且在将其定义为返回{{ 1}}我无法链接some View,因为第二个修饰符必须是ImageModifier