SwiftUI非数组场景下如何传递upcomingmeeting至MeetingProfileView
SwiftUI:将ViewModel可选属性传递至目标视图
原场景通过数组列表传递Meeting类型数据到MeetingProfileView,现新主视图不再依赖数组,需将MeetingViewModel中的可选属性upcomingmeeting作为参数传递给MeetingProfileView,以下是相关代码及最终解决方案:
ViewModel 代码
class MeetingViewModel: ObservableObject{ init(){ Task{ try await fetchAllMeetings() } Task{ try await fetchMeeting()} } @Published var upcomingmeeting: Meeting? @Published var meetings1 = [Meeting]() { didSet { if let first = meetings1.first { upcomingmeeting = first } } } }
旧主视图代码(基于数组实现)
import SwiftUI import PhotosUI struct MeetingSubView: View { @StateObject var viewModel = MeetingViewModel() var meet: Meeting var body: some View { NavigationStack{ ForEach(viewModel.meetings1) { meet in ZStack { NavigationLink(value: meet) { EmptyView() }.opacity(0.0) MeetingsRowViewDetailed(meeting: meet, viewModel: viewModel) .onAppear { if meet == viewModel.meetings1.last { print("DEBUG: Paginate here..") } } } } .navigationDestination(for: Meeting.self, destination: { meet in MeetingProfileView( meet: meet) }) }.onAppear(perform: { Task { try await viewModel.fetchMeeting()} }) } }
新主视图代码(需改造版本)
@StateObject var viewModel = MeetingViewModel() var body: some View{ VStack{ Text(viewModel.upcomingmeeting?.title ?? "no name") Text(viewModel.upcomingmeeting?.hostsite ?? "no name") } .foregroundColor(.white) .padding() }
MeetingProfileView 代码
struct MeetingProfileView: View { @StateObject var viewModel = MeetingViewModel() let meet:Meeting var body: some View { ZStack { ZStack{ KFImage(URL(string: meet.profileImageUrl ?? "")) .resizable() .scaledToFill() .frame(width: 800, height: 800) // .clipShape(Rectangle()) .opacity(0.5) .grayscale(0.8) } VStack(alignment: .center){ VStack{ Text(meet.title) .font(.title2) .fontWeight(.semibold) Text(meet.hostsite) Text(meet.notes) .padding(.horizontal, 100) .padding() .lineLimit(5) } .padding(.init(top: 50, leading: 100, bottom: 75, trailing: 100)) } Spacer() } .onAppear { viewModel.fetchTechMeet(meet) } } }
最终解决方案代码
由于upcomingmeeting是可选类型,需先安全解包再传递。通过if let解包后,使用NavigationLink直接将实例传入MeetingProfileView:
if let meet = viewModel.upcomingmeeting{ VStack{ NavigationLink(destination: MeetingProfileView(meet: meet)) { InputView3(title: viewModel.upcomingmeeting?.title ?? "", time: viewModel.upcomingmeeting?.hostsite ?? "", room: viewModel.upcomingmeeting?.citystate ?? "") } } }
内容的提问来源于stack exchange,提问作者johnny
相关产品推荐
相关产品推荐

