Я слушал @sonle об использовании NavigationStack. Я думаю, что что-то идет не так. Он осуществляет навигацию, но не так, как я ожидал, до пункта назначения в разделе «Детали путешествия». Это выглядит так.
NavigationLink(destination: {
TravelDetail(TourID: item.id)
}, label: {
TourItemView(tableItem: item)
})
------------ВОПРОС ------------
У меня есть ScrollView, содержимое которого генерируется ForEach, анализируя элементы в struct Array. Я надеюсь, что нажатие на разные ячейки приведет к странице сведений и загрузит информацию о соответствующих объектах. Как я могу этого добиться?
Я обертываю стиль каждой ячейки в кнопку и планирую выполнить действие по изменению страницы через событие нажатия кнопки. В то же время я получаю идентификатор элемента на странице списка и загружаю содержимое на страницу сведений после перехода на страницу. Я пытаюсь использовать NavigationView для прыжков, но меня смущает расположение NavigationLink. Я хочу знать, нормальный ли это метод.
Я думаю, что это основной вопрос, но я в тупике. Как видите, я новичок, поэтому, если у вас есть какие-либо справочные методы, предоставьте их мне. Большое спасибо!
И если есть необходимость предоставить другие части кода, пожалуйста, дайте мне знать.
Страница списка:
import SwiftUI
struct ContentView: View {
var tableItems: [TableItem]
init() {
var items = [TableItem]()
for index in 0..<tour.count {
let tourItem = [tour[index]]
let userItem = [user[index]]
let tableItem = TableItem(tourItem: tourItem, user: userItem)
items.append(tableItem)
}
self.tableItems = items
}
var body: some View {
NavigationView {
VStack {
ScrollView(.vertical){
VStack(spacing: 8){
ForEach(tableItems, id: \.id) { item in
Button(action: {
}) {
TourItemView(tableItem: item)
}//ButtonStyle
}//ForEach
}//VStack
}//ScrollView
}//VStack
.padding()
}//NavigationView
}//view
}//ContentView
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Подробная страница:
import SwiftUI
struct TravelDetail: View {
//let DetailItem: TravelDetailConstant
var ItemID: String
var result: TravelDetailConstant?
init(TourID: String) {
self.ItemID = TourID
result = initializersTourItem(id: ItemID)
}
func initializersTourItem(id: String)-> TravelDetailConstant {
guard let register = ContentView().tableItems.first(where: { $0.id == id }),
let initTour = tour.first(where: { $0.id == id }),
let initUser = user.first(where: { $0.id == initTour.mainKeeper })
else {
return TravelDetailConstant(
imagetext: "",
title: "",
startTime: "",
finishTime: "",
place: "",
peopleNum: "",
detailLocaltion: "",
meetingPlace: "",
tag: nil,
detailContent: "",
userImage: "",
userNikename: "",
userGender: "",
userBadge: []
)
}
let detail = TravelDetailConstant(imagetext: register.tourImage, title: register.title, startTime: register.startTime, finishTime: initTour.finishTime, place: register.location, peopleNum: register.peopeleNum, detailLocaltion: initTour.detailLocaltion, meetingPlace: initTour.meetingPlace, tag: register.tag, detailContent: initTour.detailContent, userImage: register.userImage, userNikename: register.userName, userGender: initUser.userGender, userBadge: initUser.userBadge)
return detail
}
var body: some View {
VStack{
Spacer()
.frame(height: 20)
HStack{
Image((result?.userImage)!)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 75, height: 75)
.clipShape(Circle())
.background(
Circle()
.padding(-2)
.foregroundColor(Color("DesignLightMutedOrange"))
)
.padding(.leading, 15)
VStack{
HStack{
Text((result?.userNikename)!)
.frame(width: 186, height: 28)
.padding(.trailing, 12)
Image((result?.userGender)!)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 24, height: 24)
}
.padding(.bottom, 4)
ScrollView(.horizontal) {
Button(action: {}) {
Image("")
}
}
.frame(width: 186, height: 28)
}
Button(action: { }) {
Image("heart")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 24, height: 24)
.padding(.trailing, 15)
}
}
Spacer().frame(height: 20)
HStack{
Button(action: {
}){
Text("Detail")
}
.frame(width: 150, height: 52, alignment: .leading)
.background(Color .red)
.padding(.leading, 0)
Button(action: {
}){
Text("Q&A")
}
.frame(width: 150, height: 52, alignment: .leading)
.background(Color .gray)
.listRowInsets(EdgeInsets())
Spacer()
}
Spacer()
}
}
}
struct TravelDetail_Previews: PreviewProvider {
static var previews: some View {
TravelDetail(TourID: "")
}
}
Я знаю. Однако я не понимаю, где реализовать код.
Поскольку NavigationView устарел, я предлагаю вместо него использовать NavigationStack. Что-то вроде:
struct ContentView: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
VStack {
....
//Other stuff
Button(action: {
path.append(item)
}, label: {
TourItemView(tableItem: item)
})
//OR
//NavigationLink(value: item) {
// TourItemView(tableItem: item)
//}
}
.navigationDestination(for: TableItem.self) { item in
TourItemView(tableItem: item)
}
}
}
}
Ваша TableItem
модель должна полностью соответствовать Hashable
протоколу.
struct TableItem: Hashable {
...
}
Я понимаю. Кажется, NavigationLink более разумен. Но я безуспешно пытался перейти на страницу сведений. После нажатия отображается только одна ячейка. Я обновляю свою NavigationLink, спасибо
Вы уверены, что? Даже несмотря на то, что NavigationView
устарел, использование NavigationLink(destination:)
должно работать. Можете ли вы отредактировать ОП?
Оно делает. но не перейти в нужное место. Редактирую ситуацию в вопросе.
Если вы используете NavigationLink таким образом, вам также не нужно реализовывать .navigationDestination(for:)
, как показано выше, достаточно NavigationLink(destination:)
. Я рекомендую переписать NavigationStack с нуля, чтобы сначала понять, как его использовать.
Извините за беспокойство. Оказывается, я забыл установить NavigationLink в настроенной ячейке. Теперь проблема решена, спасибо!
Ознакомьтесь с документацией по навигации в SwiftUI. Вам не хватает
NavigationLink
.