swiftui Could not cast value of type 'SwiftUI.Text' (0x2211789e8) to 'SwiftUI._ViewModifier_Content<User.PopUpViewModifier>

huangapple go评论55阅读模式
英文:

swiftui Could not cast value of type 'SwiftUI.Text' (0x2211789e8) to 'SwiftUI._ViewModifier_Content<User.PopUpViewModifier>

问题

你的代码有一个问题。在PopUpViewModifierbody方法中,你应该使用self.content而不是content。修复后的代码如下:

struct PopUpViewModifier: ViewModifier {
    @Binding var isPresented: Bool
    var content: Content
    
    func body(content: Content) -> some View {
        self.content
            .sheet(isPresented: $isPresented, onDismiss: { UIImpactFeedbackGenerator(style: .medium).impactOccurred() }) {
                self.content
            }
    }
}

此更改应该解决你遇到的致命错误。

英文:

I'm trying to create a modifier that builds a sheet with content on any View.

struct ContentView: View {
    @State private var open: Bool = false
    
    var body: some View {
        VStack {
            Image(systemName: &quot;globe&quot;)
                .imageScale(.large)
                .foregroundColor(.accentColor)
            
            Button(&quot;Open sheet&quot;) {
                open.toggle()
            }
        }
        .padding()
        .popUpModifier(isPresented: $open) {
            Text(&quot;Hello, world!&quot;)
        }
    }
}

Here's the modifier:

struct PopUpViewModifier: ViewModifier {
    @Binding var isPresented: Bool
    var content: Content
    
    func body(content: Content) -&gt; some View {
        content
            .sheet(isPresented: $isPresented, onDismiss: {UIImpactFeedbackGenerator(style: .medium).impactOccurred()}) {
                content
            }
    }
}

And here's the View's extension:

extension View {
    func popUpModifier&lt;Content: View&gt;(isPresented: Binding&lt;Bool&gt;, content: @escaping () -&gt; Content) -&gt; some View {
        self
            .modifier(PopUpViewModifier(isPresented: isPresented, content: content() as! PopUpViewModifier.Content))
    }
}

Whenever I run it I get a fatal error:

Could not cast value of type &#39;SwiftUI.Text&#39; (0x2211789e8) to &#39;SwiftUI._ViewModifier_Content&lt;User.PopUpViewModifier&gt;

It happens no matter which content I include in the modifier content brackets.
Also - without content() as! PopUpViewModifier.Content) XCode won't compile and raise alert

> Cannot convert value of type 'Content' to expected argument type 'PopUpViewModifier.Content' (aka '_ViewModifier_Content<PopUpViewModifier>')

Any suggestions?

答案1

得分: 1

你正在混淆了通常由ViewModifier接受的“内容”(即它修改的内容)与你尝试在弹出窗口中显示的内容。

目前,你试图使用一个变量同时用于呈现content和从content中的内容,基本上是递归。

为弹出窗口内容设置一个单独的变量可以解决这个问题:

struct ContentView: View {
    @State private var open: Bool = false
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            
            Button("打开弹出窗口") {
                open.toggle()
            }
        }
        .padding()
        .popUpModifier(isPresented: $open) {
            Text("你好,世界!")
        }
    }
}

struct PopUpViewModifier<T: View>: ViewModifier {
    @Binding var isPresented: Bool
    var popupContent: () -> T
    
    func body(content: Content) -> some View {
        content
            .sheet(isPresented: $isPresented, onDismiss: {UIImpactFeedbackGenerator(style: .medium).impactOccurred()}) {
                popupContent()
            }
    }
}

extension View {
    func popUpModifier<T: View>(isPresented: Binding<Bool>, popupContent: @escaping () -> T) -> some View {
        self
            .modifier(PopUpViewModifier(isPresented: isPresented, popupContent: popupContent))
    }
}
英文:

You're mixing the content that a ViewModifier normally takes (ie the content that it modifies) with the content that you're attempting to show in your popup.

Right now, you're trying to use one variable for both, presenting a sheet with that content from the content -- basically, recursion.

Setting up a separate variable for the sheet content solves this:

struct ContentView: View {
    @State private var open: Bool = false
    
    var body: some View {
        VStack {
            Image(systemName: &quot;globe&quot;)
                .imageScale(.large)
                .foregroundColor(.accentColor)
            
            Button(&quot;Open sheet&quot;) {
                open.toggle()
            }
        }
        .padding()
        .popUpModifier(isPresented: $open) {
            Text(&quot;Hello, world!&quot;)
        }
    }
}

struct PopUpViewModifier&lt;T: View&gt;: ViewModifier {
    @Binding var isPresented: Bool
    var popupContent: () -&gt; T
    
    func body(content: Content) -&gt; some View {
        content
            .sheet(isPresented: $isPresented, onDismiss: {UIImpactFeedbackGenerator(style: .medium).impactOccurred()}) {
                popupContent()
            }
    }
}

extension View {
    func popUpModifier&lt;T: View&gt;(isPresented: Binding&lt;Bool&gt;, popupContent: @escaping () -&gt; T) -&gt; some View {
        self
            .modifier(PopUpViewModifier(isPresented: isPresented, popupContent: popupContent))
    }
}

huangapple
  • 本文由 发表于 2023年4月11日 06:08:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75981104.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定