【问题标题】:When last item in list is HStack, app crashes当列表中的最后一项是 HStack 时,应用程序崩溃
【发布时间】:2019-11-12 20:48:59
【问题描述】:

我正在做一个关于我的学校建筑和楼层的应用程序,并且我使用导航视图,但是,我不想查看披露指示器,所以我发现“hack”将导航链接宽度设置为 0 以及不透明度。当我还想使用最后一个 NavigationLink 执行此操作时,我的应用程序在初始化期间访问错误的 App Delegate 文件中崩溃。当我不在最后一项上使用 HStack 和这个“hack”时,它看起来像其他列表行,但不会执行任何操作。它的唯一工作方式是下一个视图位于导航链接内,这会导致主屏幕的最后一个列表行看起来不同。有任何想法吗?非常感谢你。

import SwiftUI

struct BuildingsView: View {

    init() {
        UITableView.appearance().separatorStyle = .none
    }

    var body: some View {
        NavigationView {
            List {
                HStack{
                    BuildingCardView(titleString: "Námestie J. Herdu", subtitleString: "Námestie J. Herdu 2, Trnava", imageString: "namjherdu", infoString: "Rektorát, FMK, FF, FPV, internáty, jedáleň, kancelárie")
                    NavigationLink(destination: NamJHerduView()) {
                    EmptyView()}
                        .frame(width: 0)
                        .opacity(0)
                }
                HStack {
                    BuildingCardView(titleString: "Hajdóczyho", subtitleString: "Jána Hajdóczyho 1, Trnava", imageString: "hajdoczy", infoString: "Knižnica, učebne, kancelárie, Kino OKO")
                    NavigationLink(destination: HajdoczyhoView()) {
                    EmptyView()}
                        .frame(width: 0)
                        .opacity(0)
                }
                HStack {
                    BuildingCardView(titleString: "Bučianska", subtitleString: "Bučianska 4A, Trnava", imageString: "bucianska", infoString: "FSV, FMK, aula, kancelárie")
                    NavigationLink(destination: BucianskaView()) {
                    EmptyView()}
                        .frame(width: 0)
                        .opacity(0)
                }
                HStack {
                    BuildingCardView(titleString: "V Jame", subtitleString: "V Jame 3, Trnava", imageString: "vjame", infoString: "FMK, FSV, jedáleň")
                    NavigationLink(destination: VJameView()) {
                    EmptyView()}
                        .frame(width: 0)
                        .opacity(0)
                }
                HStack {
                    BuildingCardView(titleString: "Skladová", subtitleString: "Skladová 3, Trnava", imageString: "skladova", infoString: "FMK")
                    NavigationLink(destination: SkladovaView()) {
                    EmptyView()}
                        .frame(width: 0)
                        .opacity(0)
                }
                    NavigationLink(destination: SpacinceView()) {
                    BuildingCardView(titleString: "Špačince", subtitleString: "Hlavná 6, Špačince", imageString: "spacince", infoString: "FPV, výskumné laboratóriá")}
            }
            .navigationBarTitle(
                Text("Budovy UCM"), displayMode: .large).navigationBarHidden(false)
        }
    }
}
import SwiftUI

struct BuildingCardView: View {

    let titleString: String?
    let subtitleString: String?
    let imageString: String?
    let infoString: String?

    init(titleString: String? = "null", subtitleString: String? = "null", imageString: String? = "default", infoString: String? = "null"){

        self.titleString = titleString
        self.subtitleString = subtitleString
        self.imageString = imageString
        self.infoString = infoString
    }

    var body: some View {
        VStack {
               Image(imageString!)
               .resizable()
               .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 150, alignment: .topLeading)
               HStack {
                   VStack(alignment: .leading) {
                       Text(titleString!)
                           .font(.title)
                           .fontWeight(.black)
                           .foregroundColor(.primary)
                           .lineLimit(1)
                       Text(subtitleString!)
                           .font(.headline)
                           .foregroundColor(.secondary)
                           .lineLimit(3)
                       Text(infoString!)
                           .font(.subheadline)
                           .foregroundColor(.secondary)
                           .lineLimit(3)
                   }
                   .layoutPriority(100)
                   Spacer()
               }
               .padding()
        }
            .cornerRadius(10)
            .overlay(
                RoundedRectangle(cornerRadius: 10)
                    .stroke(Color(.sRGB, red: 150/255, green: 150/255, blue: 150/255, opacity: 0.2), lineWidth: 1)
            )
    }
}
import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView{
            BuildingsView()
                .tabItem {
                    Image(systemName: "house")
                    Text("Budovy")
            }
            Text("Vyhľadávanie TBD")
                .tabItem {
                    Image(systemName: "magnifyingglass")
                    Text("Vyhľadávanie")
                }
            MapView()
                .tabItem {
                    Image(systemName: "map")
                    Text("Mapa")
            }
        }
    }
}

【问题讨论】:

  • 不幸的是你有很多代码......但仍然不够。最简单的方法是给我们一个指向 github 的链接,我们可以在其中轻松下载您的问题......或者您以这种方式分解您的代码,只有一些编码行会重现错误。

标签: swift swiftui swiftui-list


【解决方案1】:

这应该至少可以解决五个问题:
- 你的最后一张卡片看起来不一样
- “内联模式”中的导航栏没有转到屏幕的上角(您可以在屏幕截图中看到)
- 您可以单击相应卡片周围的边框以打开NavigationLink
- 图像被拉伸
- 如果您想在任何地方毫无问题地使用列表,您现在就可以做到。在我修复之前,这些列表将不再有分隔符。

但请注意,如果您想更改ContentView 的背景颜色,我的建议UIScrollView.appearance().backgroundColor = UIColor(named: "CustomScrollViewBackgroundColor") 并不总是能正常工作。因此,如果您对此有任何疑问,我可以向您推荐thisthis 问题。

import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView {
            NavigationView {
                BuildingsView()
            }
                .tabItem {
                    Image(systemName: "house")
                    Text("Budovy")
                }

            Text("Vyhľadávanie TBD")
                .tabItem {
                    Image(systemName: "magnifyingglass")
                    Text("Vyhľadávanie")
                }
            MapView()
                .tabItem {
                    Image(systemName: "map")
                    Text("Mapa")
                }
        } .edgesIgnoringSafeArea(.top)
    }
}

struct BuildingsView: View {
    var body: some View {
        // UIScrollView.appearance().backgroundColor = UIColor(named: "CustomScrollViewBackgroundColor") // If you want to change the background color

        return ScrollView {
            VStack {
                NavigationLink(destination: NamJHerduView()) {
                    BuildingCardView(titleString: "Námestie J. Herdu", subtitleString: "Námestie J. Herdu 2, Trnava", imageString: "namjherdu", infoString: "Rektorát, FMK, FF, FPV, internáty, jedáleň, kancelárie")
                } .buttonStyle(PlainButtonStyle()) // This is needed because the system considers the content in the NavigationLink as a button. And buttons are colored blue by system default.
                NavigationLink(destination: HajdoczyhoView()) {
                    BuildingCardView(titleString: "Hajdóczyho", subtitleString: "Jána Hajdóczyho 1, Trnava", imageString: "hajdoczy", infoString: "Knižnica, učebne, kancelárie, Kino OKO")
                } .buttonStyle(PlainButtonStyle())
                NavigationLink(destination: BucianskaView()) {
                    BuildingCardView(titleString: "Bučianska", subtitleString: "Bučianska 4A, Trnava", imageString: "bucianska", infoString: "FSV, FMK, aula, kancelárie")
                } .buttonStyle(PlainButtonStyle())
                NavigationLink(destination: VJameView()) {
                    BuildingCardView(titleString: "V Jame", subtitleString: "V Jame 3, Trnava", imageString: "vjame", infoString: "FMK, FSV, jedáleň")
                } .buttonStyle(PlainButtonStyle())
                NavigationLink(destination: SkladovaView()) {
                    BuildingCardView(titleString: "Skladová", subtitleString: "Skladová 3, Trnava", imageString: "skladova", infoString: "FMK")
                } .buttonStyle(PlainButtonStyle())
                NavigationLink(destination: SpacinceView()) {
                    BuildingCardView(titleString: "Špačince", subtitleString: "Hlavná 6, Špačince", imageString: "spacince", infoString: "FPV, výskumné laboratóriá")
                } .buttonStyle(PlainButtonStyle())
            } .padding(.horizontal).padding(.bottom)
        }

        .navigationBarTitle(Text("Budovy UCM"))
    }
}

struct BuildingCardView: View {

    let titleString: String?
    let subtitleString: String?
    let imageString: String?
    let infoString: String?

    init(titleString: String? = "null", subtitleString: String? = "null", imageString: String? = "default", infoString: String? = "null"){

        self.titleString = titleString
        self.subtitleString = subtitleString
        self.imageString = imageString
        self.infoString = infoString
    }

    var body: some View {
        VStack(spacing: 0) {
            Image(imageString!)
                .resizable()
                .aspectRatio(contentMode: .fit) // You should not use frame for resizing the image otherwise it be will stretched
            HStack {
                VStack(alignment: .leading, spacing: 0) {
                    Text(titleString!)
                        .font(.title)
                        .fontWeight(.black)
                        .foregroundColor(.primary)
                        .lineLimit(1)
                    Text(subtitleString!)
                        .font(.headline)
                        .foregroundColor(.secondary)
                        .lineLimit(3)
                    Text(infoString!)
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                        .lineLimit(3)
                }
                .layoutPriority(100)

                Spacer()
            }
            .padding(.all, 16)
            // .background(Color("CustomCardBackgroundColor")) // If you want to change the background color of your cards
        }
        .cornerRadius(10)
        .overlay(
            RoundedRectangle(cornerRadius: 10)
                .stroke(Color(.sRGB, red: 150/255, green: 150/255, blue: 150/255, opacity: 0.2), lineWidth: 1)
        )
    }
}

【讨论】:

  • 谢谢,这似乎可行,但是当在struct BuildingsView 中调用它时,我现在如何在代码中的struct BuildingCardView 中向 NavigationLink(destination: EmptyView()) 发送不同的视图? .. 因为从我的代码 sn-p 中可以看出,我向那里发送了 6 个不同的视图,例如 SpacinskaView() 等。
  • 对不起,我忘记了。但我更新了我的答案,它现在应该可以工作了。
  • 现在我还有一个小问题,当我单击“卡片”中的空白区域时(例如,不在文本或图像上),它没有作为按钮响应,单击图像或卡片中的文本正确导航到下一个视图。这有可能解决吗?
  • 我发现这是因为PlainButtonStyle(),因为当我不在NavigationLink上使用它时,整张卡片都是可点击的
  • 哦,是的。发生这种情况是因为那里根本什么都没有。但是你可以通过给卡片一个背景来快速解决问题。在我的代码中,我已经描述了如何做到这一点。如果你给卡片一个透明的背景,它也应该工作。但是,如果您想正确使用不透明背景和深色模式,则需要自定义颜色集。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多