2016-06-18 219 views
1

在我的程序中我有14個不同的按鈕,每個都有一個字母。每個按鈕都通過自動佈局相互連接。所以有很多的限制。見第一圖像解釋:自動佈局和動畫

enter image description here

但我希望能夠通過UIAnimation移動每一個按鍵來回不搞亂整個汽車佈局設置。見第二圖像解釋,我想做的事:

enter image description here

現在的代碼我目前使用得到這些動畫:

self.letterA.translatesAutoresizingMaskIntoConstraints = YES; 
[UIView animateWithDuration:0.2 animations:^{ 
    [letterA setFrame:CGRectMake(x, y, width, height)]; 
}]; 

現在程序完美的作品!絕對沒有問題!但唯一的「問題」是這樣的代碼在控制檯中生成此消息:

Unable to simultaneously satisfy constraints. 
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 

而且此警告/錯誤/問題的推移和和好幾次,每一次一個UIButton移動。現在我該怎麼辦?

  1. 我可以忽略Unable to simultaneously satisfy constraints嗎?或者會在路上造成麻煩?
  2. 如果不是,如何解決它?而且由於涉及到大量的約束條件,如何在不編輯每一個約束的情況下修復?
  3. 我非常想繼續使用動畫setFrame:

回答

2

要貴點:

  1. 「我可以忽略無法同時滿足的約束警告」 號這是一個非常糟糕的主意忽略這一點,即使在UI出現或多或少的,只要你想它甚至有警告。這意味着系統正在決定如何渲染布局,因爲您提供的說明是矛盾的。它分析了您提供的約束條件,並找到了一種通過破壞其中一個或多個創建一致佈局的方法。不能保證它會決定在不同的屏幕尺寸或操作系統版本上打破相同的限制。忽略此警告大量增加了UI錯誤的可能性。

  2. 我會重新考慮這個UI的設計方式。 IB/Storyboard Autolay適用於UI達到一定複雜程度的情況。這個用戶界面看起來稍微超出了複雜程度 - 如果不需要移動,就沒問題。當他們這樣做時,程序化的自動佈局可能會讓事情變得更簡單。 我會採取的方法如下。

    a。創建一個圖塊對象,該圖塊公開了頂部,左側,寬度和高度約束的NSLayoutConstraint屬性。 (這些約束將被添加到超級視圖上,但也存儲在瓦片本身上)。

    b。使用工廠對象方法設置視圖,以新瓦片的起始位置偏移量,寬度和高度作爲參數。使用這些值獨立設置每個圖塊的約束。不要將瓷磚互相約束 - 所有約束都應該是內部(寬度,高度)或相對於superview(x,y)。這意味着當您更改動畫時,只有一個圖塊受到影響。你實際上有更多的約束,但它們在代碼中,因此更容易管理。 c)。使用UIView動畫來移動瓷磚並使用瓷磚上的約束來調整它們的大小。您可以存儲每個圖塊位置的初始幀並使用這些值來確定目標約束值。您應該可以輕鬆地通過這種方式調整瓷磚的位置和大小。

    d)。蘋果的NSLayoutConstraint的API有點冗長和難看。考慮使用Masonry,一個更好的Autolayout DSL,以保持您的代碼清潔。

  3. 只要您不使用Autolayout,您可以繼續使用-setFrame:--這兩種方法只是不能很好地協同工作。如果您希望您的應用在多個屏幕尺寸上運行,則需要使用Autolayout,否則重新計算每個幀並在代碼中動態偏移。如果你不這樣做(也許它是一個iPad應用程序,你不關心專業版,那麼只需使用-setFrame:)。但總的來說,我建議咬住子彈,然後學習Autolayout

1

如果您使用自動佈局,你應該設置translateAutoResizingMask爲false,否則你會繼續收到此錯誤。相反,您應該只在動畫塊之前使用約束設置新位置,然後在動畫塊中調用layoutIfNeeded。當您在界面構建器中設置具有將自動將translateAutoResizingMaskToConstraints設置爲false的效果的約束時。