Использование SwiftUI для каждого, чтобы определить, какое представление добавить в список
Я пытаюсь воссоздать UIKit ниже в SwiftUI с помощью ForEach
func configureCell(for post: MediaPost, in tableview: UITableView) -> UITableViewCell {
if let post = post as? TextPost {
let cell = tableview.dequeueReusableCell(withIdentifier: CellType.text) as! TextPostCell
return cell
} else{
guard let post = post as? ImagePost else { fatalError("Unknown Cell") }
return cell
}
}
Вот моя модель
protocol PostAble {
var id:UUID { get }
}
struct MediaPost: PostAble,Identifiable {
let id = UUID()
let textBody: String?
let userName: String
let timestamp: Date
let uiImage: UIImage?
}
struct RetweetMediaPost: PostAble,Identifiable {
let id = UUID()
let userName: String
let timestamp: Date
let post: MediaPost
}
Итак, я создал массив в ViewModel
class PostViewModel: ObservableObject {
@Published var posts: [PostAble] = []
}
и я хотел бы повторить этот массив с помощью ForEach и создать список представлений. Вот код, который я написал
struct PostListView: View {
@ObservedObject var postViewModel = PostViewModel()
var body: some View {
List {
ForEach(postViewModel.posts, id: \.id) { post in
if let post = post as? MediaPost {
PostView(post: post)
} else {
guard let post = post as Retweet else { fatalError("Unknown Type") }
RetweetView(post: post)
}
}
}
}
}
Что дает мне эту ошибку
Тип "()" не может соответствовать "Просмотр"; только типы struct/enum/class могут соответствовать протоколам
Я понимаю ошибку и знаю, почему она не работает, но у меня нет другого решения для перезаписи. Можно ли этого добиться с помощью swiftUI?
1 ответ
Попробуйте следующее. Протестировано с Xcode 11.4 / iOS 13.4.
Примечание: вы создали модель представления внутри представления, поэтому убедитесь, что вы заполнили ее также в представлении, например. в.onAppear, в противном случае просто объявите, что он предоставлен извне
struct PostListView: View {
@ObservedObject var postViewModel = PostViewModel()
// @ObservedObject var postViewModel: PostViewModel // for external !!
var body: some View {
List {
ForEach(postViewModel.posts, id: \.id) { post in
self.view(for: post)
}
}
}
private func view(for post: PostAble) -> some View {
let mediapost = post as? MediaPost
let retweet = post as? RetweetMediaPost
return Group {
if mediapost != nil {
PostView(post: mediapost!)
}
if retweet != nil {
RetweetView(post: retweet!)
}
}
}
}