我有一个带有一些标签的UIViewController和一个UICollectionView。 UICollectionView表示从xib加载的自制日历。当我点击一个集合视图单元格(例如,选择日历中的一天)时,我会相应地更改基础模型,并且需要更新标签。但是,点击时没有任何更新。
我有一个更新标签并在viewDidLoad()中调用它的方法。第一次加载后,所有标签都变为nil,将标签声明为'var'而不是'weak var'并没有帮助。当在viewController的self.view上调用一些诸如layoutSubviews()的函数时,标签似乎存在,viewDidLoad()(和updateLabels())被调用,但是屏幕上没有任何变化。 我尝试使用xib创建一个带有标签的UIView(子类),并以编程方式将这些标签直接放置在viewController中,将所有代码放在一个位置-结果相同。 setNeedsDisplay(),生命周期方法,删除-添加到superview-这些都不适合我。我是在做错什么还是错过了重要的事情?
class ChallengeViewController: UIViewController {
var challenge = Challenge(title: Challenge.sampleTitle, startDate: Challenge.sampleStartDate, durationInDays: 40, checkIns: [Bool](repeating: true, count: 40), cheatDaysPlanned: 2, isActive: true, roundNumber: 1, pointsScored: 0)
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var calendarView: CalendarView!
@IBOutlet weak var statisticsView: ChallengeStatisticsView!
//contains labels that should be updated
override func viewDidLoad() {
super.viewDidLoad()
calendarView.challenge = challenge
calendarView.updateMonthAndYearLabels(for: challenge)
statisticsView.updateLabels()
titleLabel.text = challenge.title
}
}
class CalendarView: UIView {
var challenge: Challenge?
//other code here
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "calendarCell", for: indexPath) as! CalendarCollectionViewCell
collectionView.performBatchUpdates({
if let challenge = challenge {
cell.update(challenge: challenge)
let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ChallengeScreenViewController") as! ChallengeViewController
viewController.view.layoutSubviews()
viewController.challenge = challenge
viewController.updateLabels()
collectionView.reloadItems(at: [indexPath])
}
}, completion: nil)
}
}
答案 0 :(得分:1)
您正在cell.update
中创建一个全新的视图控制器,并且它永远不会出现在屏幕上,这就是为什么您看不到任何更新的原因。不知道您的update
方法实际上是做什么的,但是似乎只需调用self.updateLabels()
或self.statisticsView.updateLabels()
就可以解决问题。由于您似乎同时拥有两者,因此不确定。
答案 1 :(得分:0)
为什么要重新加载VC?
当您单击collectionViewCell时,创建一个委托协议来告诉VC用数据模型重新加载标签。
答案 2 :(得分:0)
cellForItem(at:)
方法获取选定的单元格func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! CalendarCollectionViewCell
if let challenge = challenge {
cell.update(challenge: challenge)
collectionView.reloadItems(at: [indexPath])
self.updateLabels()
}
}
答案 3 :(得分:0)
我不知道UIStoryboard(name:, bundle:).instantiateViewController(withIdentifier:)
创建了一个全新的vc,这是主要的错误。
因此,我决定使用Notification Center来使控制器响应模型的更改。
现在一切正常。
class CalendarView: UIView {
var challenge: Challenge?
//other code here
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "calendarCell", for: indexPath) as! CalendarCollectionViewCell
collectionView.performBatchUpdates({
if let challenge = challenge {
cell.update(challenge: challenge)
// assigning a new value to calendarView's own variable, posting the notification
self.challenge = challenge
let name = Notification.Name("CellTapped")
NotificationCenter.default.post(name: name, object: nil)
collectionView.reloadItems(at: [indexPath])
}
}, completion: nil)
}
}
class ChallengeViewController: UIViewController {
var challenge = Challenge(title: Challenge.sampleTitle, startDate: Challenge.sampleStartDate, durationInDays: 40, checkIns: [Bool](repeating: true, count: 40), cheatDaysPlanned: 2, isActive: true, roundNumber: 1, pointsScored: 0)
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var calendarView: CalendarView!
@IBOutlet weak var statisticsView: ChallengeStatisticsView!
// taking the changed variable from calendarView when the notification is posted
@objc func updateAfterTap() {
if let calendarViewChallenge = calendarView.challenge {
self.challenge = calendarViewChallenge
statisticsView.updateLabels()
}
}
override func viewDidLoad() {
super.viewDidLoad()
calendarView.challenge = challenge
calendarView.updateMonthAndYearLabels(for: challenge)
statisticsView.updateLabels()
titleLabel.text = challenge.title
NotificationCenter.default.addObserver(self, selector: #selector(self.updateAfterTap), name: Notification.Name("CellTapped"), object: nil)
}
}