DynamicViewContent 的 ViewModifier?

问题描述 投票:0回答:1

我想做这样的事情:

struct HandleUrlDropModifier<Content>: ViewModifier where Content: DynamicViewContent {
    @Environment(\.modelContext) var modelContext

    var content: Content

    func body(content: Content) -> some View {
        content
            .dropDestination(for: URL.self) { items, index in
                // index is Int
                handleUrlDrop(items, at: index)
            }
    }

    func handleUrlDrop(_ items: [URL], at index: Int) {
        modelContext.insert(...)
    }
}

这可能吗?


我尝试过的事情

将其写为直接扩展是行不通的,因为我想使用

@Environtment
变量:

extension DynamicViewContent {
    @Environment(\.modelContext) var modelContext // <- not possible
    
    func handleUrlDrop() -> some View {
        self
        .dropDestination(for: URL.self) { items, index in
            modelContext.insert(...)
        }
   }
}

这适用于常规视图,但

.dropDestination
action
对于
DynamicViewContent
来说是不同的:

struct HandleUrlDropModifier: ViewModifier {
    @Environment(\.modelContext) var modelContext

    func body(content: Content) -> some View {
        content
            .dropDestination(for: URL.self) { items, location in
                // location is CGPoint
                handleUrlDrop(items)
                return true
            }
    }

    func handleUrlDrop(_ items: [URL]) {
        modelContext.insert(...)
    }
}
swift swiftui viewmodifier
1个回答
0
投票

代替视图修饰符,编写一个

View
来包装
DynamicViewContent
并添加
dropDestination
修饰符。然后你可以用
DynamicViewContent
扩展来包装这个视图,这样它看起来就像一个视图修饰符。

// this view can conform to DynamicViewContent too!
struct HandleURLDropView<Content: DynamicViewContent>: DynamicViewContent {
    
    @Environment(\.modelContext) var modelContext

    let content: Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        content.dropDestination(for: URL.self) { items, index in
            handleUrlDrop(items)
        }
    }

    func handleUrlDrop(_ items: [URL]) {
        // ...
    }
    
    // DynamicViewContent conformance
    var data: Content.Data { content.data }
}

extension DynamicViewContent {
    func handleURLDrop() -> some DynamicViewContent {
        HandleURLDropView {
            self
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.