使用 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:关闭第一个工作表时如何显示第二个工作表

SwiftUI - 在 UIWindow 上显示视图

SwiftUI:为 .sheet(_: onDismiss:) 重置状态

SwiftUI - 如何防止工作表中的键盘向上推我的主 UI

UIKit 中等效的 SwiftUI 工作表视图是啥?