2014-10-07 58 views
2

因此,在編譯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),但我終於找到了解決方案,並在此處發佈了該問題,以供將來爲我和其他人員參考。

回答

1

這樣使得它的行爲變化,是不是這樣做:

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

1

這似乎是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