自定义SwiftUI视图,其中ViewBuilder参数将View作为参数

9ceoxa92  于 2023-05-16  发布在  Swift
关注(0)|答案(1)|浏览(146)

我无法允许ViewBuilder参数用于自定义视图,该自定义视图将另一个视图作为参数。
就像这样:@ViewBuilder imageElementContent: @escaping (ElementView) -> EnclosingView)
这是我目前无法编译的草稿:

struct AsyncCouponImageRendererView<ImageView, EnclosingView>: View where ImageView: View, EnclosingView: View {
    @ObservedObject private var model: AsyncCouponImageRendererModel
    private let imageElementContent: (ImageView) -> EnclosingView

    /// - Parameters:
    ///   - couponImages: List of images to be rendered as list of SwiftUI Images (CouponImage → UImage → Image)
    ///   - tandemRendering: Render the images consecutively (one behind the other). Pending image renderings will be represented with a Progress View
    @MainActor init(couponImages: [CouponImage], tandemRendering: Bool = true, @ViewBuilder imageElementContent: @escaping (ImageView) -> EnclosingView) {
        self.model = AsyncCouponImageRendererModel(couponImages: couponImages, tandemRendering: tandemRendering)
        self.imageElementContent = imageElementContent
    }
    
    @MainActor init(couponImages: [CouponImage], tandemRendering: Bool = true) where EnclosingView == ZStack<ImageView> { // edited based Dávid Pásztor's answer
        self.init(couponImages: couponImages, tandemRendering: tandemRendering) { view in
            ZStack {
                view
            }
        }
    }
    
    var body: some View {
        ForEach(0 ..< model.imageCount, id: \.self) { index in
            if let image = model.images[index] {
                imageElementContent(
                    Image(uiImage: image)
                        .resizable()
                        .scaledToFit() // <-- compiler complains "Cannot convert value of type 'some View' to expected argument type 'ImageView'"
                )
            } else {
                ProgressView()
            }
        }
        .onAppear {
            model.render()
        }
    }
}

编译器在.scaledToFit()行抱怨Cannot convert value of type 'some View' to expected argument type 'ImageView'
在引入ViewBuilder参数之前,一切都运行正常。

db2dz4w8

db2dz4w81#

在导致编译器错误的第二个init中,您隐式地定义了EnclosingView的类型。
你需要告诉编译器,只有当EnclosingView确实等于你隐式使用的类型,即ZStack<ImageView>时,这个init才可用。

@MainActor init(couponImages: [CouponImage], tandemRendering: Bool = true) where EnclosingView == ZStack<ImageView> {
    self.init(couponImages: couponImages, tandemRendering: tandemRendering) { view in
        ZStack {
            view
        }
    }
}

相关问题