gpt4 book ai didi

ios - Swift/TableView 可重复使用的 Cell 每次显示时都会加载不同的内容

转载 作者:行者123 更新时间:2023-11-28 16:10:14 25 4
gpt4 key购买 nike

我有一个 UITableViewController。在第 1 节内有一个显示 JTAppleCalendar 的单元格很容易填充:

    if indexPath.section == 1 {

let cell = tableView.dequeueReusableCellWithIdentifier("calendarViewCell") as! CalendarViewCell

print(eventDatesAsNSDates)
cell.calendarView.selectDates(eventDatesAsNSDates)
return cell
}

eventDatesAsNSDatesviewDidAppear 中填充。

理论上,一切都按我想要的方式工作。但是,如果我上下滚动 TableView,就会发生以下完全令人讨厌的行为。

enter image description here

cellForRowAtIndexPath print(eventDatesAsNSDates) 中的 print 语句证明 eventDatesAsNSDates 没有改变,但日历一直被填充一次而不是另一次然后被填充再次……

cell.calendarView.selectDateseventDatesAsNSDates 均未在应用程序的其他时间设置或调用。

我错过了什么?非常感谢您的帮助。

根据要求,selectDates 函数:

public func selectDates(dates: [NSDate], triggerSelectionDelegate: Bool = true, keepSelectionIfMultiSelectionAllowed: Bool = false) {
var allIndexPathsToReload: [NSIndexPath] = []
var validDatesToSelect = dates
// If user is trying to select multiple dates with multiselection disabled, then only select the last object
if !calendarView.allowsMultipleSelection && dates.count > 0 { validDatesToSelect = [dates.last!] }

let addToIndexSetToReload = {(indexPath: NSIndexPath)->Void in
if !allIndexPathsToReload.contains(indexPath) { allIndexPathsToReload.append(indexPath) } // To avoid adding the same indexPath twice.
}

let selectTheDate = {(indexPath: NSIndexPath, date: NSDate) -> Void in
self.calendarView.selectItemAtIndexPath(indexPath, animated: false, scrollPosition: .None)
addToIndexSetToReload(indexPath)
// If triggereing is enabled, then let their delegate handle the reloading of view, else we will reload the data
if triggerSelectionDelegate {
self.internalCollectionView(self.calendarView, didSelectItemAtIndexPath: indexPath)
} else { // Although we do not want the delegate triggered, we still want counterpart cells to be selected

// Because there is no triggering of the delegate, the cell will not be added to selection and it will not be reloaded. We need to do this here
self.addCellToSelectedSetIfUnselected(indexPath, date: date)
let cellState = self.cellStateFromIndexPath(indexPath, withDate: date)
if let aSelectedCounterPartIndexPath = self.selectCounterPartCellIndexPathIfExists(indexPath, date: date, dateOwner: cellState.dateBelongsTo) {
// If there was a counterpart cell then it will also need to be reloaded
addToIndexSetToReload(aSelectedCounterPartIndexPath)
}
}
}

let deSelectTheDate = { (oldIndexPath: NSIndexPath) -> Void in
addToIndexSetToReload(oldIndexPath)
if let index = self.theSelectedIndexPaths.indexOf(oldIndexPath) {
let oldDate = self.theSelectedDates[index]
self.calendarView.deselectItemAtIndexPath(oldIndexPath, animated: false)
self.theSelectedIndexPaths.removeAtIndex(index)
self.theSelectedDates.removeAtIndex(index)

// If delegate triggering is enabled, let the delegate function handle the cell
if triggerSelectionDelegate {
self.internalCollectionView(self.calendarView, didDeselectItemAtIndexPath: oldIndexPath)
} else { // Although we do not want the delegate triggered, we still want counterpart cells to be deselected
let cellState = self.cellStateFromIndexPath(oldIndexPath, withDate: oldDate)
if let anUnselectedCounterPartIndexPath = self.deselectCounterPartCellIndexPath(oldIndexPath, date: oldDate, dateOwner: cellState.dateBelongsTo) {
// If there was a counterpart cell then it will also need to be reloaded
addToIndexSetToReload(anUnselectedCounterPartIndexPath)
}
}
}
}

for date in validDatesToSelect {
let components = self.calendar.components([.Year, .Month, .Day], fromDate: date)
let firstDayOfDate = self.calendar.dateFromComponents(components)!

// If the date is not within valid boundaries, then exit
if !(firstDayOfDate >= self.startOfMonthCache && firstDayOfDate <= self.endOfMonthCache) { continue }
let pathFromDates = self.pathsFromDates([date])

// If the date path youre searching for, doesnt exist, then return
if pathFromDates.count < 0 { continue }
let sectionIndexPath = pathFromDates[0]

// Remove old selections
if self.calendarView.allowsMultipleSelection == false { // If single selection is ON
let selectedIndexPaths = self.theSelectedIndexPaths // made a copy because the array is about to be mutated
for indexPath in selectedIndexPaths {
if indexPath != sectionIndexPath { deSelectTheDate(indexPath) }
}

// Add new selections
// Must be added here. If added in delegate didSelectItemAtIndexPath
selectTheDate(sectionIndexPath, date)
} else { // If multiple selection is on. Multiple selection behaves differently to singleselection. It behaves like a toggle. unless keepSelectionIfMultiSelectionAllowed is true.
// If user wants to force selection if multiselection is enabled, then removed the selected dates from generated dates
if keepSelectionIfMultiSelectionAllowed {
if selectedDates.contains(calendar.startOfDayForDate(date)) {
addToIndexSetToReload(sectionIndexPath)
continue // Do not deselect or select the cell. Just add it to be reloaded
}
}
if self.theSelectedIndexPaths.contains(sectionIndexPath) { // If this cell is already selected, then deselect it
deSelectTheDate(sectionIndexPath)
} else {
// Add new selections
// Must be added here. If added in delegate didSelectItemAtIndexPath
selectTheDate(sectionIndexPath, date)
}
}
}


// If triggering was false, although the selectDelegates weren't called, we do want the cell refreshed. Reload to call itemAtIndexPath
if /*triggerSelectionDelegate == false &&*/ allIndexPathsToReload.count > 0 {
delayRunOnMainThread(0.0) {
self.batchReloadIndexPaths(allIndexPathsToReload)
}
}
}

最佳答案

cellForRow 委托(delegate)方法尝试在每次您的单元格再次可见时更新 tableView 行/部分。

我肯定会在其他地方准备数据(用于日历)并且我更愿意只呈现数据。 UITableViewCell 的可重用性将正确处理内容。

不要在 cellForRow 方法中调用该方法。尝试放置它,例如进入 viewDidAppear() 方法。如果 selectDates() 方法完成了更新 tableView 的所有工作,它仍然可以工作。

关于ios - Swift/TableView 可重复使用的 Cell 每次显示时都会加载不同的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39667564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com