1

我正在尝试使用 ForEach 在 SwiftUI 中重新创建下面的 UIKit

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';只有结构/枚举/类类型可以符合协议

我理解这个错误,我知道它为什么会失败,但没有其他解决方案可以重写。这可以通过swiftUI实现吗?

4

1 回答 1

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!)
            }
        }
    }
}
于 2020-07-14T05:15:12.993 回答