使用多任务处理时视图大小发生变化时如何设置通知 |迅速

Posted

技术标签:

【中文标题】使用多任务处理时视图大小发生变化时如何设置通知 |迅速【英文标题】:How to set Notification if view size changed when using multitasking | Swift 【发布时间】:2016-03-30 01:10:55 【问题描述】:

当我在 iPad 上使用多任务测试我的应用程序并更改应用程序上的应用程序大小时,需要调整集合视图单元格的大小,否则它们不适合视图窗口。

我已经采取了一些措施,例如

改变细胞大小的检测装置 测量视图大小以确保单元格适合窗口 如果用户更改设备方向,则添加观察者

这一切都很好,但是在使用多任务处理或返回全屏应用程序时实际更改窗口大小时,单元格大小不会改变并且看起来不合适。直到通过切换方向或切换视图控制器强制执行此操作,以便再次执行 viewWillLoadviewDidLoad

那么,如果view.frame 大小发生变化,我该如何设置通知?

【问题讨论】:

如果你能在storyboard中正确设置你的约束就更好了,那么就没有什么大问题了。如果您想了解方向变化,请查看此 ..***.com/a/25667424/4874185 我在整个应用程序中,但是在使用集合视图时,我必须为单元格指定高度和宽度,这当然很棘手,因为对 iPhone 和 iPad 使用相同的尺寸可能不合适.所以我实际上划分视图大小以计算出合适的大小,例如在 iPhone 上我每行适合 3 个单元格,然后在 iPad 上我适合 6 个(cell.width = self.view.width / 6)——因为 3 看起来大得离谱。但是当使用多任务处理时,当窗口是 iPhone 的宽度并离开屏幕时,应用程序会尝试容纳 6 个单元格。 “你应该使用自动布局”这一行不会停留在表格和集合视图上。但是话虽如此,UIView 上有一个 updateConstraints 方法会在需要更新约束时被调用... 【参考方案1】:

我认为要覆盖的正确函数是viewWillTransition(to:, with:)。每当容器大小即将改变时调用它。

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) 
    super.viewWillTransition(to: size, with: coordinator)

    self.collectionView?.collectionViewLayout.invalidateLayout()

【讨论】:

【参考方案2】:

我认为您将问题复杂化了,只需使用以下内容,因此当设备旋转或调整大小时,集合视图也会相应更改。

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()

【讨论】:

谢谢,效果很好!我想这不是在用户调整大小时发出通知的问题。我现在可以清理我的一些代码了。 更一般地说,在覆盖func viewWillLayoutSubviews() 中,必须通过在多任务处理中更改视图大小来重新创建/处理视图。在我的 TableView 中,我不得不重新创建它,它运行良好。仅通过翻转横向/纵向模式并不需要惊人的重新创建/处理,而是需要多任务视图大小更改。【参考方案3】:

我尝试了 RileyDev 的回答,但应用程序进入了无限循环。

只有当应用程序的窗口边界发生变化时才会执行任何委托,因此我制作了自己的 viewWillTransition(to size 和 traitCollectionDidChange 版本。

使用下面的代码,即使特征没有改变,您也可以检测窗口边界大小的变化,并相应地调整集合视图单元格的大小,从而使集合视图布局无效。

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 进入分屏多任务模式时收到通知

当集合视图大小发生变化时,我需要帮助为 UICollectionView 单元格大小设置动画

java 当数据库数据发生变化时自动发送邮件

当 UITextView 大小发生变化时,如何调整 UITableViewCell 的大小?

处理包含能够折叠和展开的子视图的视图

当视图宽度发生变化时,如何使 UILabel 正确调整其尺寸?