我的应用程序的一个功能是自动裁剪图像。
基本的想法是,有人会拍一张纸的照片(想想:收据),然后在确定纸张边框后自动裁剪图像。
我可以使用OpenCV确定纸张的边框。所以,我接下来要做的就是更改每个指南的“中心”属性(只需2个水平线和2个垂直“线”,可以手动拖动)。
然后,在我拨打所有电话以改变4个指南中的每一个之后不久,有其他东西出现并再次设置“中心”。 (我已经覆盖了“setCenter”来证明这一点)。该中心似乎被重置: [UIView(Geometry)_applyISEngineLayoutValues] 。
我无法弄清楚为什么会发生这种情况,或者如何阻止它,但它可能与约束有关。我的观点是一个简单的UIButton。当用户点击&用他们的手指拖动它,调用一个只改变中心的动作例程。这有效。
但在另一个案例中,我提出了一个UIImagePickerController。选择图片后,我确定纸张边界,更改“指南”中心,然后在“_applyISEngineLayoutValues”中将它们全部设置回来。
知道在这种情况下发生了什么?或者我如何设置视图的中心,并让它实际停留?
答案 0 :(得分: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];
这将更新视图的位置,您不会收到任何错误。
答案 1 :(得分:3)
你正在使用自动布局,所以Fogmeister的答案是正确的,但不是每个人都可以使用自动布局 - 例如那些必须支持iPad 1的人 - 所以我会在这里留下这个答案。
如果您需要使用视图的框架,但系统正在添加约束,那么有一个解决方法;但它并不漂亮。
_applyISEngineLayoutValues
设置您的视图center
和bounds
,但不会触及frame
。如果您覆盖setCenter:
和setBounds:
无所事事,然后始终在您自己的代码中使用setFrame:
,那么_applyISEngineLayoutValues
将让您独自一人。
我对这种方法不满意,但这是迄今为止我发现阻止_applyISEngineLayoutValues
在我的布局逻辑中停留的唯一方法。