Использование SwiftUI для каждого, чтобы определить, какое представление добавить в список - PullRequest
1 голос
/ 14 июля 2020

Я пытаюсь воссоздать 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)
                }

            }
        }
    }
}

, который дает мне эту ошибку

Тип '()' не может соответствовать 'View'; только типы struct / enum / class могут соответствовать протоколам

Я понимаю ошибку и знаю, почему она не работает, но у меня нет другого решения для перезаписи. Можно ли этого добиться с помощью swiftUI?

1 Ответ

1 голос
/ 14 июля 2020

Попробуйте следующее. Протестировано с 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!)
            }
        }
    }
}
...