2013-12-10 56 views
1

我需要根據可用磁盤空間來改變子視圖的寬度。所以我有一個多數民衆贊成在視圖控制器的viewWillLayoutSubviews稱爲這樣的選擇:UIView的框架在初始加載時被Storyboard覆蓋

CGRect rect = self.usageView.bounds; 
rect.size.width = self.someCalculatedwidth; 
[self.usageView setFrame:rect]; 
[self.usageView setNeedsDisplay]; 

真的,我只是想改變子視圖的寬度。它適用於視圖控制器是初始控制器的情況;然而,如果它從一個Push Segue轉換過來,它就停止工作。會發生什麼事情,我會看到我想要的寬度,然後根據故事板上的藍圖變爲原始寬度。

行爲感覺像iOS的推SEGUE動畫期間高速緩存塊中的原始(故事板)圖,並且在完成時它執行其不具有上述我的計算的塊;從而改寫了期望的視圖。任何想法?

+0

您是否在使用自動佈局? – user1459524

+0

@ user1459524是的,我是。目前在這個特定的子視圖上沒有限制。我做了實驗並「添加了缺失的限制」,但沒有任何區別。我還在viewDidAppear中調用了我的「調整大小」選擇器,但即使該嘗試也會被恢復。調整大小選擇器的任何後續調用(例如由於方向更改,按鈕輕敲等引起的調用);只有推後繼最初的一個有問題。 – Hampden123

+0

當您在上面粘貼的代碼中忽略setNeedsDisplay的調用時會發生什麼? – user1459524

回答

2

有兩種方法。

第一種方法是爲了繞開這個問題,與一個很酷的動畫副作用。由於我不知道iOS何時或多少次執行自動約束,所以我簡單地延遲了我的UIView修改並使用動畫平滑化。所以我換景動漫周邊的代碼在我的選擇:

[UIView animateWithDuration:.25 animations:^{ 
    CGRect rect = self.usageView.bounds; 
    rect.size.width = self.someCalculatedwidth; 
    [self.usageView setFrame:rect]; 
    [self.usageView setNeedsDisplay]; 
}]; 

然後,我會打電話給我選擇在我的控制器的viewDidAppear:動畫:

[self performSelector:@selector(resetUsageView) withObject:self afterDelay:0.0]; 

現在大多數人會說這是一種逃避或一個kludge。這很公平。

第二種方法我攻擊問題的根源 - 自動佈局/約束。我在故事板中的usageView中添加一個寬度約束,並將其IBOutlet連接到我的代碼。

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *usageViewWidthConstraint; 

然後我修改約束按計算出的寬度在我的控制器的viewWillAppear中:動畫:

[self.usageViewWidthConstraint setConstant:self.someCalculatedWidth]; 

瞧!一個班輪。

現在如果我想要動畫,我從第一種方法中體會到了它的味道?那麼,約束條件的變化超出了動畫領域,所以基本上我需要第一和第二種方法的組合。我更改UIView的動畫幀,並修改約束以及「設置記錄直線」:

[UIView animateWithDuration:.25 animations:^{ 
    CGRect rect = self.usageView.bounds; 
    rect.size.width = self.someCalculatedwidth; 
    [self.usageView setFrame:rect]; 

    [self.usageViewWidthConstraint setConstant:self.someCalculatedWidth]; // <<<< 

    [self.usageView setNeedsDisplay]; 
}];