Как получить список в SwiftUI, способный указывать на несколько представлений на основе строки

Простой способ выразить это - вернуться к UITableView и получить didSelectRowAt(indexPath) функция, которая вела себя так:

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

Там, где основано на значении indexPath.row, я могу вызывать уникальный контроллер представления (например: первый - это TableView, а другие - CollectionView.

В настоящее время, основываясь на двух ответах, я могу создать следующий код:

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)
    }
}

Тем не менее, я получаю следующую ошибку с моей NavigationLink:

Значения результата в '?: выражения имеют несовпадающие типы "FirstList" и "SecondView"

Так как моя цель здесь состоит в том, чтобы иметь два разных взгляда, на которые я указываю, основываясь на названии, я хотел бы найти какой-то способ сделать эту работу.

Ответ, опубликованный superpuccio, похоже, очень близок к тому, что я хочу, но, учитывая ожидаемую сложность целевых представлений, я не думаю, что было бы целесообразно составить их полностью в NavigationLink.

2 ответа

Решение

Так как у вас есть динамический List Я предлагаю вам использовать ForEach внутри List сюда:

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)
    }
}

Я бы включил условие в пункт назначения.

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

            }
            .listStyle(GroupedListStyle())

        }
    }
Другие вопросы по тегам