2013-05-10 35 views
4

我的應用程序的一個功能是自動裁剪圖像的功能。自動佈局阻止我改變視圖的中心

其基本思想是有人會拍一張紙(想想:收據),然後在確定紙張的邊界後,圖像可以自動裁剪。

我可以通過使用OpenCV來確定紙張的邊框。所以,接下來我要做的是改變每個指南的「中心」屬性(只有2條水平線和2條垂直「線」可以手動拖動)。

然後,在我撥打我的所有電話來改變每個4個指南後不久,其他事情就會出現,並再次設置「中心」。 (我已經重寫了「setCenter」來證明這一點)。該中心似乎被重置爲:[UIView(幾何)_applyISEngineLayoutValues]

我不明白爲什麼會發生這種情況,或者如何阻止它,但它可能與約束有關。我的觀點是一個簡單的UIButton。當用戶用手指敲擊&時,會調用一個動作例程來改變中心。這工作。

但在另一種情況下,我提出了一個UIImagePickerController。在他們選擇圖片後,我確定紙張邊界,更改「指南」中心,然後在「_applyISEngineLayoutValues」後面設置它們。

任何想法在這種情況下發生了什麼?或者我可以如何設置視圖的中心,並讓它實際上留下來?

+0

我看到一個類似的東西;我將視圖的框架設置爲非零大小的框架,但是_applyISEngineLayoutValues將邊界設置爲零。 – Simon 2013-07-16 11:36:20

+0

你能展示一些代碼嗎?你是否試圖用......'someView.center = somePoint;'來改變CGPoint?如果是這樣,你不能用AutoLayout來做到這一點。 AutoLayout的第一條規則是你不能改變視圖的'frame'(讀'中心')。如果你想讓'frame'改變,那麼你必須更新任何相關約束的'constant'值,以便視圖移動到你想要的位置。 – Fogmeister 2013-07-17 08:00:44

回答

12

AutoLayout的第一條規則是,您不能直接更新視圖的frameboundscenter

您必須更新與視圖相關的約束,以便約束更新視圖。

例如,你第一垂直線將有水平的限制類似...

1. Leading edge to superview = some value. 
2. Width = some value. 

這就夠了(水平),在畫面上的這條線。

現在,如果您想將此行移至右側,您不能只更改center您必須執行此操作...

1. Create a property in you view controller like this... 

@property (nonatomic, weak) IBOutlet NSLayoutConstraint *verticalLine1LeadingConstraint; 
// or if you're coding the constraint... 
@property (nonatomic, strong) NSLayoutConstraint *verticalLine1LeadingConstraint; 

2. Save the constraint in to that property... 

// either use IB to CTRL drag the constraint to the property like any other outlet. 
// or something like... 

self.verticalLine1LeadingConstraint = [NSLayotuConstraint ... // this is the code adding the constraint... 

[self.view addConstraint:self.verticalLine1LeadingConstraint]; 

現在你有一個屬性指向此約束。

現在,當你需要「更新中心」垂直線1 ...

// Calculate the distance you want the line to be from the edge of the superview and set it on to the constraint... 

float distanceFromEdgeOfSuperview = // some calculated value... 

self.verticalLine1LeadingConstraint.constant = distanceFromEdgeOfSuperview; 

[self.view layoutIfNeeded]; 

這將更新視圖的位置,你不會得到任何錯誤。

3

您正在使用自動佈局,因此Fogmeister的答案是正確的,但不是每個人都可以使用自動佈局 - 例如,那些不得不支持iPad 1的人 - 所以我會在這裏留下這個答案。

如果您需要使用視圖的框架,但系統正在添加約束,則有一種解決方法;但並不漂亮。

_applyISEngineLayoutValues設置您的視圖的centerbounds,但不碰frame。如果你重寫setCenter:setBounds:什麼也不做,然後在你自己的代碼中總是使用setFrame:,那麼_applyISEngineLayoutValues會讓你一個人不在。

我對這種方法並不滿意,但這是我迄今爲止發現的阻止_applyISEngineLayoutValues從我所有佈局邏輯中排除的唯一方法。

+0

規則AutoLayout之一,不要更新視圖的「框架」,「邊界」或「中心」。如果您希望這些更改,請更新與該視圖相關的自動佈局約束。 – Fogmeister 2013-07-17 08:02:51

+0

我必須支持iPad 1,所以我不能使用約束。但是,在後來的iOS上,一些會自動添加;這是我發現解決這個問題的唯一方法。 – Simon 2013-07-17 08:52:29

+0

啊,對不起,沒有意識到你沒有使用AutoLayout作爲問題標題是關於使用AutoLayout。除非您編輯答案,否則我無法刪除投票。 – Fogmeister 2013-07-17 08:53:45