使用 SwiftUI 时尝试在视图中显示工作表时应用程序崩溃
Posted
技术标签:
【中文标题】使用 SwiftUI 时尝试在视图中显示工作表时应用程序崩溃【英文标题】:App Crashes when attempting to present sheet over view when using SwiftUI 【发布时间】:2019-07-25 01:23:51 【问题描述】:我正在尝试使用.sheet() 在 SwiftUI 中呈现另一个视图的视图。当它运行时,我的应用程序崩溃即使在模拟器上运行也没有堆栈跟踪,并显示此错误:
EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
我已经通过尝试呈现 Text("Test") 而不是我的自定义视图来确定正在呈现的视图不是问题,但我仍然遇到相同的错误。
.sheet(isPresented: self.$isPresenting) () -> Text in
return Text("This is a test")
这是设置视图并尝试在按下绿色按钮时显示另一个视图的代码。在设备上看起来像这样:
struct WeekView: View
@ObjectBinding var currentMealPlan = MealPlan(totalMealExchanges: 0, totalGraciesMeals: 0)
@State var isPresenting = false
var body: some View
NavigationView
VStack
VStack(alignment: .leading)
Text("Meals at Gracies remaining: ?/\(currentMealPlan.totalGraciesMeals)")
Text("Meal Exchanges Remaining: ?/\(currentMealPlan.totalMealExchanges)")
List
Section(header: Text("Monday"))
HStack
MealView(meal: "Breakfast", location: "Dorm ", color: Color.green)
.tapAction
self.isPresenting.toggle()
.sheet(isPresented: self.$isPresenting) () -> Text in
return Text("This is a test")
MealView(meal: "Lunch", location: "Gracies", color: Color.blue)
MealView(meal: "Dinner", location: "Salsarita", color: Color.yellow)
Section(header: Text("Tuesday"))
Text("Hello World")
Section(header: Text("Wednesday"))
Text("Hello World")
Section(header: Text("Thursday"))
Text("Hello World")
Section(header: Text("Friday"))
Text("Hello World")
Section(header: Text("Saturday"))
Text("Hello World")
Section(header: Text("Sunday"))
Text("Hello World")
.navigationBarTitle("This Week")
.navigationBarItems(trailing: Button(action:
, label:
Text("Help")
))
struct MealView: View
@State var meal: String
@State var location: String
@State var color: Color
@State private var showPopover = false
var body: some View
ZStack
Rectangle()
.fill(color)
VStack
Text(meal)
.bold()
Text(location)
.lineLimit(2)
class MealPlan: BindableObject
let willChange = PassthroughSubject<Void, Never>
var totalMealExchanges: Int didSet willChange.send()
var totalGraciesMeals: Int didSet willChange.send()
init(totalMealExchanges: Int, totalGraciesMeals: Int)
self.totalGraciesMeals = totalGraciesMeals
self.totalMealExchanges = totalMealExchanges
【问题讨论】:
EXC_BAD_INSTRUCTION 通常会发生,因为编译器希望找到什么都没有的东西。可能是您强制解包 nil,可能是数组索引超出范围,可能是您引用了最近被 ARC 或其他方式释放的东西。这些是常见的 3 个原因 感谢您的回复!我认为这可能是我尝试呈现简单标签而不是自定义视图(我正在解码 JSON 并将值附加到数组)的部分原因,但我仍然遇到问题。我不确定什么会被释放,因为我正在使用 SwiftUI 视图和 @State 变量,这两个 SwiftUI 都应该在幕后处理(至少这是我理解它的工作原理)。 您应该将您的MealPlan
实现添加到您的帖子中,否则我们无法重现该问题。如果我们无法重现,就不可能确定崩溃的来源。如果您不能透露您的膳食计划,请尝试将其实施减少到最低限度。在此过程中,崩溃可能会消失,您将更好地了解问题出在哪里。
@kontiki 刚刚在帖子底部添加了 MealPlan 类
【参考方案1】:
我在模拟器(iPhone Xr)上试过,它没有崩溃。我正在使用 Xcode 11 Beta 4。你的设置是什么?
我确实发现了一些错误。您在 didSet 中调用 willChange,但您应该在进行更改之前在 willSet 中调用它。你应该改变:
var totalMealExchanges: Int didSet willChange.send()
var totalGraciesMeals: Int didSet willChange.send()
到:
var totalMealExchanges: Int willSet willChange.send()
var totalGraciesMeals: Int willSet willChange.send()
【讨论】:
感谢您指出 willSet 问题:),我刚刚根据您的建议解决了这个问题。我也在运行 Xcode 11 beta 4,并且一直在 iPhone XR 模拟器中测试该应用程序。由于应用程序没有为您崩溃,是模式出现还是什么也没发生? 是的,它确实存在。 哇,真奇怪。你只是复制了我在我的问题中输入的代码吗? 是的,我确认,现在我可以重现它了。是时候向 Apple 提出一个错误了:-| 我也会这样做并参考你的第二个。干杯。【参考方案2】:这原来是 SwiftUI 中的一个错误。如果列表嵌入在导航视图中并且包含 6 个或更多部分,则应用在尝试呈现工作表时会崩溃 (FB6818276)
【讨论】:
【参考方案3】:我没有对此进行测试,但是通过将 .sheet 附加到父视图,我得到了更好的结果。尝试移动它,使其成为外部 VStack 的修饰符,而不是 MealView。
【讨论】:
刚刚尝试过,不幸的是应用程序仍然崩溃。不过还是谢谢推荐以上是关于使用 SwiftUI 时尝试在视图中显示工作表时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:.sheet() 在关闭当前工作表时不会使用预期数据转到上一个视图
SwiftUI:为 .sheet(_: onDismiss:) 重置状态