自动布局阻止我更改视图的中心

时间:2013-05-10 18:51:55

标签: ios autolayout nslayoutconstraint

我的应用程序的一个功能是自动裁剪图像。

基本的想法是,有人会拍一张纸的照片(想想:收据),然后在确定纸张边框后自动裁剪图像。

我可以使用OpenCV确定纸张的边框。所以,我接下来要做的就是更改每个指南的“中心”属性(只需2个水平线和2个垂直“线”,可以手动拖动)。

然后,在我拨打所有电话以改变4个指南中的每一个之后不久,有其他东西出现并再次设置“中心”。 (我已经覆盖了“setCenter”来证明这一点)。该中心似乎被重置: [UIView(Geometry)_applyISEngineLayoutValues]

我无法弄清楚为什么会发生这种情况,或者如何阻止它,但它可能与约束有关。我的观点是一个简单的UIButton。当用户点击&用他们的手指拖动它,调用一个只改变中心的动作例程。这有效。

但在另一个案例中,我提出了一个UIImagePickerController。选择图片后,我确定纸张边界,更改“指南”中心,然后在“_applyISEngineLayoutValues”中将它们全部设置回来。

知道在这种情况下发生了什么?或者我如何设置视图的中心,并让它实际停留?

2 个答案:

答案 0 :(得分: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];

这将更新视图的位置,您不会收到任何错误。

答案 1 :(得分:3)

你正在使用自动布局,所以Fogmeister的答案是正确的,但不是每个人都可以使用自动布局 - 例如那些必须支持iPad 1的人 - 所以我会在这里留下这个答案。

如果您需要使用视图的框架,但系统正在添加约束,那么有一个解决方法;但它并不漂亮。

_applyISEngineLayoutValues设置您的视图centerbounds,但不会触及frame。如果您覆盖setCenter:setBounds:无所事事,然后始终在您自己的代码中使用setFrame:,那么_applyISEngineLayoutValues将让您独自一人。

我对这种方法不满意,但这是迄今为止我发现阻止_applyISEngineLayoutValues在我的布局逻辑中停留的唯一方法。