1

I am doing an app about my school buildings and floors, and I use Navigation View, however, I don't want to view disclosure indicator, so I found "hack" to set navigation link width to 0 and also opacity. When I want to do it also with last NavigationLink, my app crashes in App Delegate file with Bad access during initialisation. When I don't use HStack and this "hack" on last item, it appears to look like the other list rows, but wont do any action. Only way it works is when the next view is inside Navigation Link, which causes home screen to have last List row looking differently. Any ideas? Thank you very much. Screenshot from simulator with last list row with disclosure indicator

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")
            }
        }
    }
}
Andrew
  • 26,706
  • 9
  • 85
  • 101
redearz
  • 135
  • 1
  • 9
  • unfortunately you have a lot of code there ...and still not enough. Easiest thing would be to give us a link to github where we can easily download your problem ...or you break down your code in that way, that only a some coding lines reproduce the error. – Chris Nov 15 '19 at 10:46

1 Answers1

0

That should fix at least five problems:
- That your last card looks different
- That the Navigation bar in "inline-mode" does not go to the upper corners of the screen (You can see that on the screenshot)
- That you can click on the borders around the respective cards to open the NavigationLink.
- That the images are stretched
- If you want to use a list anywhere without problems, you can do it now. Before my fix, these lists would no longer have separators.

But please note if you want to change the background color of the ContentView, that my suggestion UIScrollView.appearance().backgroundColor = UIColor(named: "CustomScrollViewBackgroundColor") does not always work correctly. So if you have any problems with that, I can recommend this and this question to you.

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)
        )
    }
}
Mattis Schulte
  • 639
  • 1
  • 10
  • 18
  • Thank you, this seems to work, but how can I now send different views to NavigationLink(destination: EmptyView()) in struct BuildingCardView in your code when calling it in struct BuildingsView? .. Because as you can see from my code snippet, I send there 6 different views like SpacinskaView() etc. – redearz Nov 20 '19 at 14:46
  • Sorry, I forgot that. But I updated my answer and it should work now. – Mattis Schulte Nov 20 '19 at 15:42
  • Now I have one small issue left, when I click on empty space in the "card" (e.g. not on text or image) it does not respond as a button, clicking on image or text in card navigates me to next view correctly. Is this possible to solve? – redearz Nov 27 '19 at 09:50
  • I found out it's because of PlainButtonStyle(), because when I don't use it on NavigationLink, whole card is clickable – redearz Nov 27 '19 at 10:06
  • Oh yes. That happens because there is simply nothing there. But you can solve the problem quickly by giving the card a background. In my code, I have described how to do it. It should also work if you give the card a transparent background. But if you want to use an opaque background and dark mode properly you need a custom color set. – Mattis Schulte Nov 27 '19 at 10:36
  • Thank you very much for explanation and help. I used systemColors to make it easily adaptable for dark mode. – redearz Nov 30 '19 at 16:54