2014-03-05 24 views
6

我想在我的應用程序中顯示一個簡單的設置屏幕,我使用Autolayout。由於我的應用支持風景,並且設置控件在手機橫向時不太適合,所以我添加了UIScrollview。UIScrollview與Autolayout風景內容大小

看來,UIScrollview和Autolayout的組合是這裏和其他地方的常見問題。我已經閱讀了一些關於它的文章,從它可以告訴的一點看,我想要做的事情的一個好方法是將我的各種控件放在一個視圖中,例如帶有約束的「contentView」在這一觀點上一致。然後讓contentView成爲UIScrollView的唯一子視圖。我有與UIScrollView的邊緣綁定約束的contentView。

UINavigationView -> UIScrollview -> contentView (UIView) -> Control Subviews 

xib

它工作在縱向細,即使我添加的內容在我的內容查看,需要滾動看到的,但是當我去的風景,它不會讓我向下滾動遠遠不夠。這就像我旋轉時內容大小被重置到可見區域的框架(或導航控制器超級視圖的框架)。

simulator

我想知道如果我需要檢查旋轉,然後在那個時候重新設定內容的大小?如果是這樣,有沒有辦法從視圖(contentView)動態地獲得這個大小?

感謝您提供的任何幫助! 吉姆

回答

7

有兩個組成部分具有自動佈局妥善處理滾動的觀點:

  1. 約束的滾動視圖的子視圖:滾動視圖的contentSize將通過滾動視圖的子視圖的約束條件來決定。因此,您需要在滾動視圖(即第二個開關)中的最後一個控件到其超級視圖(即滾動視圖)中具有底部約束。看起來你確實有這個。這些滾動視圖子視圖的約束將根據需要自動調整滾動視圖的contentSize

    順便說一下,第二個開關的底部約束的constant通常會默認爲一些較大的值,對應於它在肖像中的佈局方式。您可能需要爲最後一個控件選擇和編輯底部約束,並將其更改爲「標準」值。

    enter image description here

  2. 約束滾動視圖本身:你需要確保你有一個滾動視圖,本身的底部約束,以它的父(並確保你做有高度約束在滾動視圖上)。這將在屏幕旋轉時調整滾動視圖的frame。我想知道你的項目中是否會缺少這個。

    您可以通過運行在調試器的應用證實了這一點,打「暫停」按鈕:

    enter image description here

    ,然後在(lldb)提示符下,鍵入po [[UIWindow keyWindow] recursiveDescription],你應該看到:

    (lldb) po [[UIWindow keyWindow] recursiveDescription] 
    <UIWindow: 0x8b97ff0; frame = (0 0; 320 480); autoresize = W+H; gestureRecognizers = <NSArray: 0x8b98450>; layer = <UIWindowLayer: 0x8b97af0>> 
        | <UIView: 0x8b9a830; frame = (0 0; 320 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = RM+BM; layer = <CALayer: 0x8b9a240>> 
        | | <UIScrollView: 0x8b9aa50; frame = (0 0; 480 320); clipsToBounds = YES; autoresize = RM+TM; gestureRecognizers = <NSArray: 0x8b9a6c0>; layer = <CALayer: 0x8b9a130>; contentOffset: {0, 0}> 
        | | | <UILabel: 0x8b9ade0; frame = (20 20; 63 21); text = 'Settings'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b9aec0>> 
        | | | <UILabel: 0x8b9d590; frame = (20 49; 51 21); text = 'View 1'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b9d6b0>> 
        | | | <UILabel: 0x8b9db70; frame = (408 49; 51 21); text = 'View 2'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b9dc10>> 
        | | | <UIView: 0x8b9de60; frame = (335 78; 124 53); autoresize = RM+BM; layer = <CALayer: 0x8b9dec0>> 
        | | | <UIView: 0x8b9e000; frame = (20 78; 284 53); autoresize = RM+BM; layer = <CALayer: 0x8b9e060>> 
        | | | <UILabel: 0x8b9e250; frame = (20 139; 59 21); text = 'Slider 1'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b9e2f0>> 
        | | | <UISlider: 0x8b9e460; frame = (18 238; 444 34); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8b9e5c0>; value: 0.500000> 
        | | | | <UIView: 0x8ace410; frame = (2 16; 440 2); userInteractionEnabled = NO; layer = <CALayer: 0x8ace470>> 
        | | | | | <UIView: 0x8ace610; frame = (221 0; 219 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ace670>> 
        | | | | | | <UIView: 0x8ace6e0; frame = (-221 0; 440 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ace740>> 
        | | | | | | | <CAGradientLayer: 0x8ace7b0> (layer) 
        | | | | | <UIView: 0x8ace7e0; frame = (0 0; 221 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ace840>> 
        | | | | <UIImageView: 0x8ace9d0; frame = (207 1; 31 31); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8acea60>> 
        | | | | | <UIImageView: 0x8ace8b0; frame = (-13 -6.5; 57 43.5); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ace940>> 
        | | | <UISlider: 0x8b9e850; frame = (17 168; 444 34); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8b9e930>; value: 0.500000> 
        | | | | <UIView: 0x8ba5430; frame = (2 16; 440 2); userInteractionEnabled = NO; layer = <CALayer: 0x8ba5490>> 
        | | | | | <UIView: 0x8acc190; frame = (221 0; 219 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8acae30>> 
        | | | | | | <UIView: 0x8acc3f0; frame = (-221 0; 440 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ac84d0>> 
        | | | | | | | <CAGradientLayer: 0x8accb90> (layer) 
        | | | | | <UIView: 0x8acdf50; frame = (0 0; 221 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8acdfb0>> 
        | | | | <UIImageView: 0x8ace070; frame = (207 1; 31 31); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ace100>> 
        | | | | | <UIImageView: 0x8acdfe0; frame = (-13 -6.5; 57 43.5); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8acdc80>> 
        | | | <UILabel: 0x8b9e9c0; frame = (20 209; 59 21); text = 'Slider 2'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b9ea60>> 
        | | | <UISwitch: 0x8b9ece0; frame = (411 279; 51 31); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8b9edd0>> 
        | | | | <_UISwitchInternalViewNeueStyle1: 0x8b9f0c0; frame = (0 0; 51 31); gestureRecognizers = <NSArray: 0x8b723f0>; layer = <CALayer: 0x8b9f1c0>> 
        | | | | | <UIView: 0x8b9f750; frame = (35.5 0; 15.5 31); clipsToBounds = YES; layer = <CALayer: 0x8b9f7b0>> 
        | | | | | | <UIView: 0x8b9f3b0; frame = (-35.5 0; 51 31); layer = <CALayer: 0x8b9f410>> 
        | | | | | <UIView: 0x8b9f6c0; frame = (0 0; 35.5 31); clipsToBounds = YES; layer = <CALayer: 0x8b9f720>> 
        | | | | | | <UIView: 0x8b9f440; frame = (0 0; 51 31); layer = <CALayer: 0x8b9f4a0>> 
        | | | | | <UIView: 0x8ba11e0; frame = (0 0; 51 31); layer = <CALayer: 0x8ba1240>> 
        | | | | | | <UIImageView: 0x8ba0f10; frame = (39 16; 0 0); alpha = 0; userInteractionEnabled = NO; layer = <CALayer: 0x8ba10f0>> 
        | | | | | | <UIImageView: 0x8ba1120; frame = (12 16; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x8ba11b0>> 
        | | | | | <UIImageView: 0x8b9fab0; frame = (7 -6; 57 43.5); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ba0a40>> 
        | | | <UISwitch: 0x8b974b0; frame = (411 318; 51 31); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8b75570>> 
        | | | | <_UISwitchInternalViewNeueStyle1: 0x8b7d6a0; frame = (0 0; 51 31); gestureRecognizers = <NSArray: 0x8b845e0>; layer = <CALayer: 0x8b78750>> 
        | | | | | <UIView: 0x8b7df70; frame = (35.5 0; 15.5 31); clipsToBounds = YES; layer = <CALayer: 0x8b7be00>> 
        | | | | | | <UIView: 0x8b72410; frame = (-35.5 0; 51 31); layer = <CALayer: 0x8b7a660>> 
        | | | | | <UIView: 0x8b7ba80; frame = (0 0; 35.5 31); clipsToBounds = YES; layer = <CALayer: 0x8b7bd00>> 
        | | | | | | <UIView: 0x8b78dd0; frame = (0 0; 51 31); layer = <CALayer: 0x8b7ba20>> 
        | | | | | <UIView: 0x8b81580; frame = (0 0; 51 31); layer = <CALayer: 0x8b77ee0>> 
        | | | | | | <UIImageView: 0x8b97880; frame = (39 16; 0 0); alpha = 0; userInteractionEnabled = NO; layer = <CALayer: 0x8b7e1a0>> 
        | | | | | | <UIImageView: 0x8b77460; frame = (12 16; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x8b7e350>> 
        | | | | | <UIImageView: 0x8b80670; frame = (7 -6; 57 43.5); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8b80700>> 
        | | | <UILabel: 0x8b97cf0; frame = (335 284; 67 21); text = 'Switch 1'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b808b0>> 
        | | | <UILabel: 0x8b79d60; frame = (335 323; 67 21); text = 'Switch 2'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b77b90>> 
        | | | <UIImageView: 0x8ac44f0; frame = (476 473; 3 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x8a89130>> 
        | | | <UIImageView: 0x8ac2be0; frame = (313 316; 7 3); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x8ac2c70>> 
        | | <_UILayoutGuide: 0x8b9cb20; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x8b9e5f0>> 
        | | <_UILayoutGuide: 0x8ac4440; frame = (0 320; 0 0); hidden = YES; layer = <CALayer: 0x8a90370>> 
    

    檢查UIScrollViewframe(例如上面的代碼適用於iPhone上的風景),並確保它與屏幕大小相對應。如果您尚未定義滾動視圖和其超級視圖之間的約束,則此frame可能不正確。

+0

感謝您的信息。 我沒有嘗試過從調試器的遞歸輸出提示,所以這是一個很酷的把戲。從我的樣品差異是,我有一箇中間UIView(我稱之爲「contentView」)之間我的UIScrollView和我的滑塊和開關等 這就是說,大提示似乎是從高度約束滾動視圖。一旦我將其刪除,我就可以在肖像中一路向下滾動。事實上,它已經超過了內容(可能仍然是肖像的大小),但至少我可以達到內容!謝謝... – Jim

+0

我的意思是移除scrollview的垂直高度約束後,我可以滾動一路(甚至過去) Landscape模式的內容。當方向改變時,我可能需要在「contentView」上強制進行某種刷新以使內容匹配完全匹配,但是太高不如太短。再次感謝你的幫助。 – Jim

+0

@Jim「它超越了內容」問題可能是該開關的底部約束對容器視圖的影響,以及從容器視圖底部到滾動視圖底部的約束。沒有看到這個項目很難說。底線,如果你正確地得到你的約束,你肯定不需要在orientationSize方面改變'contentSize'。 – Rob

0

也許其他人會對此有一個更好的解決方案,但沒有改變太多對你當前的構建速度最快的將是你說該怎麼做:檢查旋轉,然後重新設定內容大小。 這將這樣做在你的設置視圖控制器實現文件:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    self.scrollView.contentSize = self.contentView.bounds.size; 
} 

...假設你已經在同一個文件網點添加到您的UIScrollView和你分別命名爲UIViewscrollViewcontentView