2013-05-10 2 views
4

Одна из особенностей моего приложения - это то, что делает автоматическую обрезку изображения.Авто макет мешает мне изменить центр представления

Основная идея заключается в том, что кто-то сфотографировал листок бумаги (думаю: квитанция), а затем изображение может автоматически обрезаться после определения границ бумаги.

Я могу определить границу бумаги с помощью OpenCV. Итак, следующее, что я делаю, - это изменить свойство «center» каждого из моих направляющих (всего две горизонтальные и две вертикальные «линии», которые можно перетащить вручную).

Затем, вскоре после того, как я сделаю все мои звонки, чтобы изменить каждый из 4-х руководств, что-то еще приходит и снова устанавливает «центр». (Я подтвердил это «setCenter», чтобы это доказать). Центр, похоже, сбрасывается следующим образом: [UIView (Geometry) _applyISEngineLayoutValues].

Я не могу понять, почему это происходит, или как остановить его, но это, вероятно, связано с ограничениями. Мой взгляд - это простой UIButton. Когда пользователь отбирает &, он нажимает на него пальцем, вызывается вызывающая программа, которая просто меняет центр. Это работает.

Но в другом случае я воспитываю UIImagePickerController. После того, как они выбирают картинку, я определяю границы бумаги, меняю «направляющие» центры, а потом «_applyISEngineLayoutValues» возвращает их обратно.

Любая идея, что происходит в этом случае? Или как я могу установить центр представления, и на самом деле он остался?

+0

Я вижу подобное; Я устанавливаю кадр представления на один с ненулевым размером, но тогда _applyISEngineLayoutValues ​​устанавливает границы равными нулю. – Simon

+0

Можете ли вы показать код. Вы пытаетесь изменить CGPoint с помощью ... 'someView.center = somePoint;'? Если это так, вы не можете сделать это с помощью AutoLayout. Первое правило AutoLayout состоит в том, что вы не можете изменить 'frame' (read' center') представления. Если вы хотите изменить «фрейм», вы должны обновить значения «константы» любых связанных ограничений, чтобы представление было перемещено туда, где вы хотите. – Fogmeister

ответ

12

Первое правило AutoLayout заключается в том, что вы не можете напрямую обновлять frame, bounds или center.

Необходимо обновить ограничения, связанные с представлением, чтобы ограничения обновляли представление.

Например, вы первая вертикальная линия будет иметь горизонтальные ограничений, что-то вроде ...

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 устанавливает center и bounds, но не касается frame. Если вы переопределите setCenter: и setBounds: ничего не делать, а затем всегда используйте setFrame: в своем собственном коде, тогда _applyISEngineLayoutValues оставит вас в покое.

Я не доволен этим подходом, но это единственный способ, которым я нашел, чтобы остановить _applyISEngineLayoutValues от pooing по всей моей логике компоновки.

+0

Правило одного из AutoLayout, не обновляйте «рамки», «границы» или «центр» представления. Если вы хотите, чтобы они изменились, обновите ограничения автоматического макета, связанные с этим представлением. – Fogmeister

+0

Я должен поддерживать iPad 1, поэтому я не могу использовать ограничения. Однако, на более поздних iOS, некоторые из них автоматически добавляются; это единственный способ, которым я нашел работу. – Simon

+0

А, извините, не понимал, что вы не используете AutoLayout, поскольку заголовок вопроса касается использования AutoLayout. Я не могу удалить голосование, если вы не отредактируете ответ. – Fogmeister