我正在尝试建立一个像这样的时间表:
时间轴中的每个单元格代表一个月,因此May是水平collectionView中的最后一个单元格。我想要的是在collectionView加载时自动滚动到可能不可见的位置,然后在单元格上调用特定函数以绘制箭头。我用于尝试执行此操作的代码如下。
override func viewDidLoad() {
super.viewDidLoad()
self.timeline.register(UINib(nibName: "TimelineMonthViewCell", bundle: nil), forCellWithReuseIdentifier: "TimelineMonthViewCell")
self.collectionView.register(UINib(nibName: "PostCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "PostCollectionViewCell")
pageControl.hidesForSinglePage = true
self.navigationItem.largeTitleDisplayMode = .never
UserService.posts(for: User.current,tagString: self.selectedTagTitles.first!) { (postStuff) in
self.posts = postStuff.0
self.postIds = postStuff.1
self.timeline.dataSource = self
self.collectionView.dataSource = self
self.timeline.delegate = self
self.collectionView.delegate = self
self.firstPostDate = self.posts.first?.timeStamp
self.currentPostDate = self.posts.last?.timeStamp
}
}
override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let indexToScrollTo = IndexPath(row: self.posts.count - 1, section: 0)
self.collectionView.scrollToItem(at: indexToScrollTo, at: .left, animated: false)
let firstPostDate = self.posts.first?.timeStamp
let diff = self.posts.last?.timeStamp.months(from: (firstPostDate?.startOfMonth())!)
//self.currentPostMonth = diff
let monthCellIndexPath = IndexPath(row: diff!, section: 0)
self.timeline.scrollToItem(at: monthCellIndexPath, at: .centeredHorizontally, animated: false)
let months = self.posts.last?.timeStamp.months(from: (self.posts.first?.timeStamp.startOfMonth())!)
print("cells are",self.timeline.indexPathsForVisibleItems)
print(months,"cell months")
if let optionalCell = self.timeline.cellForItem(at: IndexPath(row: months!, section: 0)) {
let cell = optionalCell as! TimelineMonthViewCell
let day = Calendar.current.component(.day, from: self.currentPostDate!)
cell.drawArrow(day: day)
} else {
print("cell out of range")
}
}
除了两个问题外,这几乎可行。
首先,初始单元格闪烁,然后自动滚动到最后一个单元格。我认为这是因为我使用的是viewDidAppear而不是viewWillAppear。但是,当我使用viewWillLoad时,应用崩溃,并显示错误:Thread 1: EXC_BAD_ACCESS (code=1, address=0xfffffffffffffff8)
第二,打印的self.timeline.indexPathsForVisibleItems是:[[0,0],[0,1],[0,2],[0,3],[0,4]]。因此,它查看的是前5个而不是滚动到的最后5个。然后,它找不到该单元格:“单元格超出范围”,因为索引约为28(最后一个单元格)。
那么我如何才能自动滚动到最后一个单元格并正确找到它呢?
答案 0 :(得分:1)
不要将这些行设置在当前位置
data-src
在img
上方可能会更好,以便在vc加载时利用第一次自动重新加载的优势,也可以在其位置插入
self.timeline.dataSource = self
self.collectionView.dataSource = self
self.timeline.delegate = self
self.collectionView.delegate = self
您可以在其中插入滚动代码
viewDidLoad
或在self.timeline.reloadData()
self.collectionView.reloadData()
中,如果您当前的for循环不是异步的
答案 1 :(得分:0)
我建议将滚动代码移至viewWillAppear
。这样一来,便可以在显示视图之前但在一切都可以查看之后完成。
override open func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let indexToScrollTo = IndexPath(row: self.posts.count - 1, section: 0)
self.collectionView.scrollToItem(at: indexToScrollTo, at: .left, animated: false)
let firstPost = self.posts.first?.timeStamp
let firstOfFirstMonth = firstPost?.startOfMonth()
let diff = self.posts.last?.timeStamp.months(from: firstOfFirstMonth!)
//self.currentPostMonth = diff
let monthCellIndexPath = IndexPath(row: diff!, section: 0)
self.timeline.scrollToItem(at: monthCellIndexPath, at: .centeredHorizontally, animated: false)
}