【问题标题】:iOS 9: Determine size of collection view in portrait and landscapeiOS 9:确定纵向和横向集合视图的大小
【发布时间】:2016-06-28 09:58:14
【问题描述】:

我有一个简单的 UICollectionViewController,FlowLayout 嵌入在 UINavigationController 中。

在 UICollectionViewFlowDelegate 中,我尝试根据屏幕上集合视图的实际可用大小来计算单元格的大小。

iOS 9 上的标准行为似乎是纵向状态栏为 20px 高且可见,导航栏为 44px 高且可见。横向状态栏隐藏,导航栏高度为 32px。

问题是,当我尝试根据这些数字计算单元格大小时,我在 collectionView:sizeForItemAtIndexPath 函数中得到了错误的数据。

我在这个函数中放了下面的代码来演示我得到的值

    print ("Device......: " + UIDevice.currentDevice().name)
    print ("Model.......: " + UIDevice.currentDevice().localizedModel)
    print ("Orientation.: " + String(UIDevice.currentDevice().orientation.rawValue))
    print ("View width..: " + String(self.view.bounds.size.width))
    print ("View height.: " + String(self.view.bounds.size.height))
    print ("S.bar height: " + String(UIApplication.sharedApplication().statusBarFrame.height))
    print ("S.bar hidden: " + String(UIApplication.sharedApplication().statusBarHidden))
    print ("N.bar height: " + String(self.navigationController?.navigationBar.frame.height))

当应用在 iPhone 6 模拟器上纵向启动时,我得到以下输出:

Device......: iPhone Simulator
Model.......: iPhone
Orientation.: 1
View width..: 375.0
View height.: 603.0
S.bar height: 20.0
S.bar hidden: false
N.bar height: Optional(44.0)

到目前为止,这与预期的一样好。然后当我将设备旋转到横向时,我得到了这个:

Device......: iPhone Simulator
Model.......: iPhone
Orientation.: 4
View width..: 667.0
View height.: 323.0
S.bar height: 20.0
S.bar hidden: false
N.bar height: Optional(32.0)

现在视图高度与实际视图高度相差 20px,状态栏的高度显示为 20,而实际为 0。此外,状态栏在实际隐藏时显示为可见。但它变得更加陌生。

当我将设备旋转回纵向时,我会得到这个:

Device......: iPhone Simulator
Model.......: iPhone
Orientation.: 1
View width..: 375.0
View height.: 623.0
S.bar height: 0.0
S.bar hidden: true
N.bar height: Optional(44.0)

所以看起来状态栏高度的计算有些延迟。

现在的问题是如何计算函数内集合视图可见部分的大小

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize

附注:

UIApplication.sharedApplication().statusBarHidden

在 iOS 9 中已弃用。

编辑#1:

在 iPhone 6 Plus 和 6s Plus 模拟器上,我似乎得到了预期值。 4s、5、6 和 6s 给出了问题中显示的值。

【问题讨论】:

  • 你需要使用:dispatch_async(dispatch_get_main_queue()) { println("height :(view.bounds.size.height)") println("width :(view.frame.size.width) ") // 所有其他代码都依赖于 UIDevice.current.orientation 此代码将在旋转完成(在主队列中)并且新尺寸可用后执行。

标签: swift uicollectionview height ios9 statusbar


【解决方案1】:

为什么不直接访问 UICollectionView 框架属性?

在这个方法中

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize

只需访问colllectionView.frame 并根据它计算大小。

您不应该依赖硬编码的高度值,因为这些东西在 iOS 的新版本中可能会发生变化。

【讨论】:

  • 不起作用,因为 collectionView.frame.height 返回与 self.view.bounds.size.height 相同的(错误)值。此外,问题的重点是避免硬编码值。这就是为什么我首先尝试计算大小。
  • 布局完成后是否重新加载数据?
  • 不,我没有。在didRotateFromInterfaceOrientation 中重新加载就可以了。谢谢!。附带说明:如果我不重新加载 willRotateToInterfaceOrientation 中的数据(我这样做了),那么会有非常难看的过渡视觉过渡效果。
  • 非常感谢您的帮助!再次感谢这一点。不过,由于操作系统实际上在轮换时请求新的单元格大小,因此我暂时将这个问题留为未解决的问题。由于状态栏的值关闭,因此无法正确计算它。重新加载数据只会触发第二次重新计算,据我目前的理解应该没有必要。
  • 如果你不想重新加载 UICollectionView,你可以打电话给invalidateLayout。它只会重新加载布局而不是模型。
【解决方案2】:

你需要使用:

dispatch_async(dispatch_get_main_queue()) 
   { 
      println("height :(view.bounds.size.height)") 
      println("width :(view.frame.size.width)") 
     // all other code depends on UIDevice.current.orientation 
    }

此代码将在轮换完成(在主队列中)并且新尺寸可用后执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多