캘린더를 만들려면 서브 클래스가 UICollectionViewLayout
입니다. 사용자에게 화면에 표시 할 일수와 같은 일부 설정을 변경할 수있는 권한을 부여하고 싶습니다 (기본적으로 7). UICollectionViewLayout - 화면 회전 후에 만 invalidateLayout()이 작동합니다.
나는 UserDefaults
에 저장합니다. daysToShow
func stepperValueChanged(sender:UIStepper){
stepperValue = String(Int(sender.value))
valueLabel.text = String(Int(sender.value))
UserDefaults.standard.set(String(Int(sender.value)), forKey: "daysToShow")
NotificationCenter.default.post(name: Notification.Name(rawValue: "calendarSettingsChanged"), object: nil, userInfo: nil)
}
그래서
내가 UserDefault
에 새 값을 저장 한 후, 그때 (내가 여기에 브레이크 포인트를 설정으로 실제로라는지고있는) reloadForSettingsChange
를 호출 알림을 게시하십시오 UIStepper
값이 변경 될 때마다이 메소드를 호출합니다 :
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(reloadForSettingsChange(notification:)), name: NSNotification.Name(rawValue: "calendarSettingsChanged"), object: nil)
// other code.....
}
func reloadForSettingsChange(notification:NSNotification){
// here I save the user setting in a variable declared in my custom UICollectionViewLayout
self.calendarView.daysToShow = Int(UserDefaults.standard.string(forKey: "daysToShow")!)
self.calendarView.daysToShowOnScreen = Int(UserDefaults.standard.string(forKey: "daysToShow")!)
self.calendarView.forceReload(reloadEvent: true)
}
func forceReload(reloadEvent:Bool){
DispatchQueue.main.async {
if reloadEvent{
self.groupEventsByDays()
self.weekFlowLayout?.invalidateCacheLayout()
self.collectionView.reloadData()
}
}
}
func invalidateCacheLayout(){
self.needsToPopulateAttributesForAllSections = true
self.cachedDayDateComponents?.removeAllObjects()
self.cachedStartTimeDateComponents?.removeAllObjects()
self.cachedEndTimeDateComponents?.removeAllObjects()
self.cachedCurrentDateComponents?.removeAllObjects()
self.cachedEarliestHour = Int.max
self.cachedLatestHour = Int.min
self.cachedMaxColumnHeight = CGFloat.leastNormalMagnitude
self.cachedColumnHeights?.removeAllObjects()
self.cachedEarliestHours?.removeAllObjects()
self.cachedLatestHours?.removeAllObjects()
self.itemAttributes?.removeAllObjects()
self.allAttributes?.removeAllObjects()
_layoutAttributes.removeAll()
self.invalidateLayout()
}
문제는 레이아웃이 업데이트되지 않는 것입니다 (무효?) I (즉 풍경에서에 세로) 화면 장치를 회전 할 때까지.
func rotated() {
switch UIDevice.current.orientation {
case .landscapeLeft, .landscapeRight:
calendarView.forceReload(reloadEvent: true)
default:
calendarView.forceReload(reloadEvent: true)
}
}