过去 4 小时我一直在尝试解决此错误。它构建完美运行良好。但是当我在提要上向上滑动以重新加载时,它崩溃了。
它应该做的是,您拥有包含所有最新帖子的主页,然后向上滑动以重新加载该页面。向上滑动时,它会在顶部显示一个旋转轮,它会从提要中删除所有图像,并将新的和更新的图像带回来。 (这是一个非常糟糕的解释)。
感谢任何帮助。而且我提供了我的整个班级只是为了确保我不会错过我应该发送的任何代码。
这是我的 FeedController.swift 类
import Firebase
private let reuseIdentifier = "Cell"
class FeedController: UICollectionViewController {
// MARK: - Lifecycle
private var posts = [Post]()
var post: Post?
override func viewDidLoad() {
super.viewDidLoad()
configureUI()
fetchPosts()
}
//MARK: - Actions
@objc func handleRefresh() {
posts.removeAll()
fetchPosts()
}
@objc func handleLogout() {
do {
try Auth.auth().signOut()
let controller = LoginController()
controller.delegate = self.tabBarController as? MainTabController
let nav = UINavigationController(rootViewController: controller)
nav.modalPresentationStyle = .fullScreen
self.present(nav, animated: true, completion: nil)
} catch {
print("DEBUG: Failed to sign out")
}
}
// MARK: - API
func fetchPosts() {
guard post == nil else { return }
PostService.fetchPosts { posts in
self.posts = posts
self.collectionView.refreshControl?.endRefreshing()
self.collectionView.reloadData()
}
}
// MARK: - Helpers
func configureUI() {
collectionView.backgroundColor = .white
collectionView.register(FeedCell.self, forCellWithReuseIdentifier: reuseIdentifier)
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Logout",
style: .plain,
target: self,
action: #selector(handleLogout))
navigationItem.title = "Feed"
let refresher = UIRefreshControl()
refresher.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
collectionView.refreshControl = refresher
}
}
// MARK: - UIcollectionViewDataSource
extension FeedController {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return post == nil ? posts.count : 1
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! FeedCell
if let post = post {
cell.viewModel = PostViewModel(post: post)
} else {
cell.viewModel = PostViewModel(post: posts[indexPath.row])
}
return cell
}
}
// MARK: - UICollectionViewDelegateFlowLayout
extension FeedController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = view.frame.width
var height = width + 8 + 40 + 8
height += 50
height += 60
return CGSize(width: width, height: height)
}
}
这是给我错误的行(刷新后)
cell.viewModel = PostViewModel(post: posts[indexPath.row])
答案 0 :(得分:0)
Ans:当你没有得到任何数据时,显示虚拟数据或返回 0 个单元格。
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if post.count == nil { return 0 } else { return post.count
}
问题:如果数据为 nil 时返回 1,这意味着编译器返回一个单元格。当该单元格的每个元素都绑定到数组中的特定值时。由于 post 数组为 nil,它返回范围异常的索引。
答案 1 :(得分:0)
覆盖 func collectionView(_collectionView:UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! FeedCell
if let post = post {
cell.viewModel = PostViewModel(post: post)
} else {
if posts.count != 0{
cell.viewModel = PostViewModel(post: posts[indexPath.row])
}
}
return cell
}