英文:
swiftui Could not cast value of type 'SwiftUI.Text' (0x2211789e8) to 'SwiftUI._ViewModifier_Content<User.PopUpViewModifier>
问题
你的代码有一个问题。在PopUpViewModifier
的body
方法中,你应该使用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: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Button("Open sheet") {
open.toggle()
}
}
.padding()
.popUpModifier(isPresented: $open) {
Text("Hello, world!")
}
}
}
Here's the modifier:
struct PopUpViewModifier: ViewModifier {
@Binding var isPresented: Bool
var content: Content
func body(content: Content) -> some View {
content
.sheet(isPresented: $isPresented, onDismiss: {UIImpactFeedbackGenerator(style: .medium).impactOccurred()}) {
content
}
}
}
And here's the View's extension:
extension View {
func popUpModifier<Content: View>(isPresented: Binding<Bool>, content: @escaping () -> Content) -> 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 'SwiftUI.Text' (0x2211789e8) to 'SwiftUI._ViewModifier_Content<User.PopUpViewModifier>
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: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Button("Open sheet") {
open.toggle()
}
}
.padding()
.popUpModifier(isPresented: $open) {
Text("Hello, world!")
}
}
}
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))
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论