如果使用多任务时视图大小发生变化,如何设置通知 | Swift
How to set Notification if view size changed when using multitasking | Swift
在 iPad 上使用多任务测试我的应用程序时,我更改了应用程序上的应用程序大小,需要调整集合视图单元格的大小,否则它们不适合视图 window.
我已经采取了一些措施,例如
- 正在检测改变单元格大小的设备
- 测量视图大小以确保单元格适合 window
- 如果用户更改设备方向则添加观察者
这一切都很好,但是当使用多任务处理或返回全屏应用程序时实际更改 window 大小时,单元格大小不会改变并且看起来不合适。直到通过切换方向或切换视图控制器强制执行 viewWillLoad
或 viewDidLoad
再次执行。
那么,如果 view.frame
大小发生变化,我该如何设置通知呢?
我认为你把问题复杂化了,只需使用以下内容,这样当设备旋转或调整大小时,集合视图也会相应地发生变化。
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
guard let collectionLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else {
return
}
if UIApplication.shared.statusBarOrientation == UIInterfaceOrientation.landscapeLeft ||
UIApplication.shared.statusBarOrientation == UIInterfaceOrientation.landscapeRight {
//here you can do the logic for the cell size if phone is in landscape
} else {
//logic if not landscape
}
collectionLayout.invalidateLayout()
}
我认为要覆盖的正确函数是 viewWillTransition(to:, with:)
。每当容器大小即将更改时调用它。
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
self.collectionView?.collectionViewLayout.invalidateLayout()
}
我尝试了 RileyDev 的回答,但应用程序进入了无限循环。
当应用程序的 window 边界改变时,没有委托被执行,所以我制作了我自己的 viewWillTransition 版本(大小和 traitCollectionDidChange。
使用下面的代码,即使特征没有改变,您也可以检测到 window 边界大小调整变化,并相应地调整集合视图单元格的大小,使集合视图布局无效。
var previousWindowBounds: CGRect?
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if let currentBounds = view.window?.bounds,
let previousWindowBounds = previousWindowBounds, currentBounds != previousWindowBounds {
collectionView?.collectionViewLayout.invalidateLayout()
}
previousWindowBounds = view.window?.bounds
}
在 iPad 上使用多任务测试我的应用程序时,我更改了应用程序上的应用程序大小,需要调整集合视图单元格的大小,否则它们不适合视图 window.
我已经采取了一些措施,例如
- 正在检测改变单元格大小的设备
- 测量视图大小以确保单元格适合 window
- 如果用户更改设备方向则添加观察者
这一切都很好,但是当使用多任务处理或返回全屏应用程序时实际更改 window 大小时,单元格大小不会改变并且看起来不合适。直到通过切换方向或切换视图控制器强制执行 viewWillLoad
或 viewDidLoad
再次执行。
那么,如果 view.frame
大小发生变化,我该如何设置通知呢?
我认为你把问题复杂化了,只需使用以下内容,这样当设备旋转或调整大小时,集合视图也会相应地发生变化。
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
guard let collectionLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else {
return
}
if UIApplication.shared.statusBarOrientation == UIInterfaceOrientation.landscapeLeft ||
UIApplication.shared.statusBarOrientation == UIInterfaceOrientation.landscapeRight {
//here you can do the logic for the cell size if phone is in landscape
} else {
//logic if not landscape
}
collectionLayout.invalidateLayout()
}
我认为要覆盖的正确函数是 viewWillTransition(to:, with:)
。每当容器大小即将更改时调用它。
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
self.collectionView?.collectionViewLayout.invalidateLayout()
}
我尝试了 RileyDev 的回答,但应用程序进入了无限循环。
当应用程序的 window 边界改变时,没有委托被执行,所以我制作了我自己的 viewWillTransition 版本(大小和 traitCollectionDidChange。
使用下面的代码,即使特征没有改变,您也可以检测到 window 边界大小调整变化,并相应地调整集合视图单元格的大小,使集合视图布局无效。
var previousWindowBounds: CGRect?
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if let currentBounds = view.window?.bounds,
let previousWindowBounds = previousWindowBounds, currentBounds != previousWindowBounds {
collectionView?.collectionViewLayout.invalidateLayout()
}
previousWindowBounds = view.window?.bounds
}