0

A simple way to express this would be to go back to UITableView and have a didSelectRowAt(indexPath) function that behaved like this:

if (indexPath.row == 0) { ... } else { ... }

Where based upon the indexPath.row value, I can call a unique view controller (ex: the first one is a TableView and the others are CollectionViews.

Currently, based upon the two answers thus far, I can produce the following code:

import SwiftUI

struct MenuItem {
    let title: String
    let isEnabled: Bool
}

struct HomeList: View {
    let menuItems = [
        MenuItem(title: "ABC", isEnabled: true),
        MenuItem(title: "DEF", isEnabled: false),
        MenuItem(title: "GHI", isEnabled: true)
    ]

    var body: some View {
        NavigationView {
            List {
                ForEach(menuItems.indices, id: \.self) { index in
                    NavigationLink(destination: menuItems[index].title == "ABC" ?
                        FirstList() :
                        SecondView(menuItem: menuItems[index])) {
                        HomeRow(menuItem: menuItems[index])
                    }
                }
            }
        }
    }
}

struct HomeRow: View {
    var menuItem: MenuItem

    var body: some View {
        HStack {
            Text(verbatim: menuItem.title)
        }
    }
}

struct FirstList: View {
    var body: some View {
            List(1 ..< 5) { index in
                Text("Row \(index)")
            }
            .listStyle(GroupedListStyle())
    }
}

struct SecondView: View {
    var menuItem: MenuItem

    var body: some View {
        Text(menuItem.title)
    }
}

However, I get the following error with my NavigationLink:

Result values in '? :' expression have mismatching types 'FirstList' and 'SecondView'

Since my goal here is to have two different views I point to based upon the title, I'd like to find some way to make that work.

The answer posted by superpuccio seems to be pretty close to what I want, but with the expected complexity of the target views, I do not think it would be feasible to compose them entirely within NavigationLink.

CodeBender
  • 35,668
  • 12
  • 125
  • 132

2 Answers2

1

I would include the condition in the destination.

var body: some View {
        NavigationView {
            List(1 ..< 5) { idx in
                NavigationLink(destination:
                    idx < 3 ? Text("1111") : Text("2222") ) {
                    Text("Row \(idx)")
                }

            }
            .listStyle(GroupedListStyle())

        }
    }
Marc T.
  • 5,090
  • 1
  • 23
  • 40
  • I have updated my question with a few changes I made with naming and my HomeRow initializer, as well as showing the `HomeMenuItem` struct. However, where you use `idx < 3 ? ...`, my attempt at accessing the properties of my`menuItem` struct fails and only offers `_self`. – CodeBender Aug 06 '19 at 14:12
1

Since you have a dynamic List I suggest you use a ForEach inside a List this way:

import SwiftUI

struct MenuItem {
    let title: String
    let isEnabled: Bool
}

struct HomeList: View {
    let menuItems = [
        MenuItem(title: "ABC", isEnabled: true),
        MenuItem(title: "DEF", isEnabled: false),
        MenuItem(title: "GHI", isEnabled: true)
    ]

    var body: some View {
        let firstRowModel = menuItems[0]
        let actualModel = menuItems[1...menuItems.count-1]

        return NavigationView {
            List {
                NavigationLink(destination: FirstList()) {
                    HomeRow(menuItem: firstRowModel)
                }
                ForEach(actualModel.indices, id: \.self) { index in
                    NavigationLink(destination: SecondView(menuItem: actualModel[index])) {
                        HomeRow(menuItem: actualModel[index])
                    }
                }
            }
        }
    }
}

struct HomeRow: View {
    var menuItem: MenuItem

    var body: some View {
        HStack {
            Text(verbatim: menuItem.title)
        }
    }
}

struct FirstList: View {
    var body: some View {
            List(1 ..< 5) { index in
                Text("Row \(index)")
            }
            .listStyle(GroupedListStyle())
    }
}

struct SecondView: View {
    var menuItem: MenuItem

    var body: some View {
        Text(menuItem.title)
    }
}
superpuccio
  • 11,674
  • 8
  • 65
  • 93
  • Using your code, I can get a basic concept working, but when I try to scale it up to what I will eventually need, I encounter an error. I have updated the question with enough code to hopefully convey what I am trying to accomplish. – CodeBender Aug 06 '19 at 22:52
  • @CodeBender take a look at my EDIT and let me know if it helps. – superpuccio Aug 07 '19 at 11:00