首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI - GeometryReader崩溃

SwiftUI - GeometryReader崩溃
EN

Stack Overflow用户
提问于 2020-08-12 08:12:28
回答 2查看 753关注 0票数 0

我试图根据设备宽度实现两个不同的视图。因此,这个视图的iPad版本应该与iPhone版本不同。为此,我使用GeometryReader检查宽度。然而,应用程序总是崩溃与“线程1:信号SIGABRT”。每个人对自己工作的看法都很好。

如果我在宽度小于592的iPad的Splitscreen中启动它,它可以正常工作。我可以在没撞车的情况下把它换成大尺寸的。如果开始时宽度大于592,则会崩溃。

另外,如果我只使用if语句而不使用其他语句,它就能工作。

甚至顶部的测试也会崩溃。

这里我的代码:

代码语言:javascript
复制
import SwiftUI

struct DetailView: View {
    
    let food: FoodList
    
    @State var showRightMenu = false
    
    var body: some View {
        GeometryReader { bounds in
            ZStack (alignment: .topLeading) {

                // Test
                if bounds.size.width > 592 {
                    Text("Test")
                } else {
                    Text("Test1")
                    Text("Test2")
                }

                // Actual code
//                if bounds.size.width > 592 {
//                    HStack {
//                        FoodDetailPadViewLeft(food: self.food)
//                            .frame(width: bounds.size.width / 2)
//
//                        FoodDetailPadViewRight(food: self.food)
//                    }
//                } else {
//                    ScrollView {
//                        FoodDetailViewImage(food: self.food)
//                            .animation(.none)
//
//                        FoodDetailViewNutris(food: self.food)
//
//                        Spacer()
//                    }
//                }
                
                HStack {
                    BackButton()
                    Spacer()
                    InfoButton(showRightMenu: self.$showRightMenu)
                }
            }
            .background(Color("background"))
            .edgesIgnoringSafeArea(.all)
            .navigationBarTitle("")
            .navigationBarHidden(true)
            .navigationBarBackButtonHidden(true)
        }
    }
}

下面是一些可重复的代码:

代码语言:javascript
复制
import SwiftUI

struct ContentView: View {
    @State var foodlist: [FoodList] = Bundle.main.decode("ingredientsList.json")
    
    var body: some View {
        
        NavigationView {
            List {
                ForEach(foodlist) { food in
                    NavigationLink (destination: TestView(food: food)) {
                        Text(food.name)
                    }
                }
            }
        }
    }
}


struct TestView: View {
    let food: FoodList
    
    var body: some View {
        GeometryReader { bounds in
            ZStack (alignment: .topLeading) {
                
                if bounds.size.width > 592 {
                    Text(self.food.name)
                } else {
                    Text(self.food.name)
                    Text(self.food.category)
                }
            }
        }
    }
}



struct FoodList: Codable, Identifiable, Hashable {
    let id: Int
    let category: String
    let name: String
}


extension Bundle {
    func decode<T: Codable>(_ file: String) -> T {
        guard let url = self.url(forResource: file, withExtension: nil) else {
            fatalError("Failed to locate \(file) in bundle.")
        }
        
        guard let data = try? Data (contentsOf: url) else {
            fatalError("Failed to load \(file) from bundle.")
        }
        
        let decoder = JSONDecoder()
        
        guard let loaded = try? decoder.decode(T.self, from: data) else {
            fatalError("Failed to decode \(file) from bundle.")
        }
        
        return loaded
    }
}

和Json档案:

代码语言:javascript
复制
[
    {
      "id": 1,
      "category": "vegetables",
      "name": "Tomato",
    },
    {
      "id": 2,
      "category": "vegetables",
      "name": "Potato",
    }
]

有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-12 09:28:07

在这种情况下,最好显式地检查您需要的内容:

代码语言:javascript
复制
var body: some View {
    ZStack (alignment: .topLeading) {
        if UIDevice.current.userInterfaceIdiom == .pad {
            Text(self.food.name)
        } else {
            Text(self.food.name)
            Text(self.food.category)
        }
    }
}

注意:崩溃的发生是由于堆栈上的布局发生了更改,而这是因为相同布局堆栈上的GeometryReader得到了不同的值(首先是.zero,其次是真实的),因此在同一个布局堆栈上激活了条件的不同分支,这使SwiftUI呈现引擎变得疯狂。(你可以向苹果提交这方面的反馈,但很难解决,因为它是鸡蛋问题-几何读写器总是两次)。

票数 0
EN

Stack Overflow用户

发布于 2020-08-12 12:01:51

如果这是正确的解决方案,则不需要执行,但是当宽度大于592时,我使用不透明度来隐藏视图。

似乎是暂时有效的。

代码语言:javascript
复制
    var body: some View {
        GeometryReader { bounds in
            ZStack (alignment: .topLeading) {
                
                Text(self.food.name)
                    .opacity(bounds.size.width > 592 ? 0 : 1)
                
                VStack {
                    Text(self.food.name)
                    Text(self.food.category)
                }
                .opacity(bounds.size.width <= 592 ? 0 : 1)
            }
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63372463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档