iOS 8 UITableView旋转缺陷

问题描述:

因此,在编译XCode 6上的应用程序之后,我注意到只有在iOS 8上运行时才会出现一个奇怪的错误:UITableView在更新其框架后采用错误的内部尺寸。iOS 8 UITableView旋转缺陷

现在我将尝试解释确切的情况: 我们有一个UITableView在它的侧面旋转,基本上是水平的UITableView。它发生在tableView.transform = CGAffineTransformMakeRotation(-M_PI/2);。 现在设置变换后,然后设置其框架 - 一切都很好。 但是,当然系统在大多数情况下会向父级发送另一个帧更改,因为它需要将父级设置为实际大小,而不是XIB大小或任何初始化大小。那一刻 - 当我重新展示子视图,包括表格视图时,一切都出错了。 实际上,表格视图的框架只是设置为包含视图的bounds,但随后是内部滚动视图(在iOS 8中UITableView内部有另一个UIScrollView,称为UITableViewWrapperView。由于UITableView本身就是UIScrollView,弄清楚为什么他们需要另一个......)需要一个“高度”,它等于父宽度。而“高度”其实就是width属性,只能旋转。

现在,我们可以很容易地估计他们有一个错误与有关内UIScrollView的宽度父UITableView,这有可能是通过读取.frame.size.width代替.bounds.size.width的实际宽度。 但奇怪的是,当调查UITableView的子视图的框架 - 它们似乎都很好!所以一定是在某处出现问题。因为单元格的“高度”是320而不是568,而单元格的“宽度”很好,设置为320.

我会很高兴听到其他遇到此问题的人(或来自Apple),但我终于找到了解决方案,并在此处发布了该问题,以供将来为我和其他人员参考。

这样使得它的行为变化,是不是这样做:

- (void)layoutSubviews 
{ 
    tableView.frame = self.bounds; 
} 

我已经重置变换,设置框架,其中的UITableView会后变换本地预期的范围,然后设置转换并设置正确的框架。这有点令人困惑,但这里有:

- (void)layoutSubviews 
{ 
    if (UIDevice.currentDevice.systemVersion.floatValue >= 8.f) 
    { 
     // iOS 8 layout bug! Table's "height" taken from "width" after changing frame. But then if we cancel transform, set width/height to the final width/height, and rotate it and set to the virtual width/height - it works! 

     CGRect rotatedFrame = self.bounds, 
     unrotatedFrame = rotatedFrame; 
     unrotatedFrame.size.width = rotatedFrame.size.height; 
     unrotatedFrame.size.height = rotatedFrame.size.width; 

     tableView.transform = CGAffineTransformIdentity; 
     tableView.frame = unrotatedFrame; 
     tableView.transform = CGAffineTransformMakeRotation(-M_PI/2); 
     tableView.frame = rotatedFrame; 
    } 
    else 
    { 
     tableView.frame = self.bounds; 
    } 
} 
+0

有趣的是,这适用于我的模拟器,但不适用于实际的iPad – canton7 2014-10-20 10:36:20

+0

它适用于我 - 那么当您在iPad上工作时,您可能会采取不同的做法吗?也许是不同的方向?或不同的iOS版本? – 2014-10-20 12:50:29

+1

原来有另一个细节。在运行粘贴到答案中的代码之前,不得设置tableView的框架。我设置tableView.frame = self.bounds,然后调用您的解决方法代码(CGRect rotatedFrame = tableView.frame;等)。这会导致SIM卡正常工作,但这是一个展示相同问题的真实设备。 – canton7 2014-10-20 16:01:55

这似乎是iOS8的一个新问题。当你想旋转一个物体时,它不会再围绕物体框架的左上角旋转。

iOS8的Apple文档声明“一个对象围绕它的中心点旋转”。所以当垂直UITableView旋转90度时,它可能会从视图中消失,因为中心点可能不在可见区域。为了使表格看起来好像是围绕表格的左上角旋转的,现在您还必须将帧的翻译量等于帧宽度和帧高度之间的差值。

要注意你需要连接的变换,以获得期望的结果,就像下面这一点很重要:

首先创建一个90度的旋转变换:

CGAffineTransform xform_rotate = CGAffineTransformMakeRotation(-M_PI * 0.5); 

然后创建一个翻译量变量等于表格宽度和高度之差:

float translateAmount = (camThumbsTableView.frame.size.height/2)-(camThumbsTableView.frame.size.width/2); 

然后将原始旋转变换与tran slation:

CGAffineTransform xform_total = CGAffineTransformTranslate(xform_rotate, translateAmount, translateAmount); 

完成后,现在您可以将您的tableView如下:

self.camThumbsTableView.transform = xform_total; 

这将有旋转和平移您的tableView,使得它现在似乎已围绕其旋转的效果在tableView的左上角,而不是关于中心点。

+0

这绝对不是*问题。正如我在旋转之后设置框架*一样,不关心'anchorPoint'。有一个简单的90度旋转变换,没有任何连接。 感谢您的尝试,虽然:-)但这个答案属于其他问题... – 2014-10-14 19:41:55

+0

我确实觉得有一个地方的错误,但我的代码是否适用于iPhone。对于iPad,我想我明白你的观点。该表似乎旋转,但框架没有。因此,在iPad上,您需要将故事板中的框架设置为旋转后的旋转方式,即使旋转表格也不会移动。但对于iPhone来说工作方式不同。对于iPhone,当您旋转桌面时,框架随之移动!因此,在iPhone故事板上,您需要在旋转之前设置框架的旋转方式,然后按照上述顺序旋转。去搞清楚。 – TNBtech 2014-10-14 20:11:48

+0

那么如果这是我的问题,我甚至不会抱怨。因为这是你仍然可以控制的东西......但是,发生在我身上的是tableview中的渲染*乱七八糟!所以我发现了一个黑客来重新计算它的内部边界,但它并不漂亮。 – 2014-10-14 22:00:39