4

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

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

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

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

我不知道为什么会发生这种情况,或者如何阻止它,但它可能与约束有关。我的观点是一个简单的 UIButton。当用户用手指点击并拖动它时,会调用一个动作例程,它只会改变中心。这行得通。

但在另一种情况下,我提出了一个 UIImagePickerController。在他们选择图片后,我确定纸张边界,更改“指南”中心,然后在“_applyISEngineLayoutValues”上将它们全部重新设置。

知道在这种情况下发生了什么吗?或者我如何设置视图的中心,并让它真正保持不变?

4

2 回答 2

12

AutoLayout 的第一条规则是您不能直接更新视图的frame,boundscenter

您必须更新与视图相关的约束,以便约束更新视图。

例如,您的第一条垂直线将具有水平约束,例如...

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];

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

于 2013-07-17T08:12:12.930 回答
3

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

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

_applyISEngineLayoutValues设置您的视图centerbounds,但不触摸frame。如果您覆盖setCenter:setBounds:什么都不做,然后总是setFrame:在您自己的代码中使用,那么_applyISEngineLayoutValues您将独自一人。

我对这种方法不满意,但这是迄今为止我发现的唯一方法,可以停止_applyISEngineLayoutValues在我的布局逻辑上大便。

于 2013-07-17T07:49:45.413 回答