Auto layout prevents me from changing the viewing center

One of the features of my application is that it does automatic cropping of the image.

The main idea is that someone photographed a piece of paper (I think: a receipt), and then the image can be cropped automatically after the borders of the paper are determined.

I can determine the border of paper using OpenCV. So, the next thing I do is change the "center" property of each of my guides (there are only two horizontal and two vertical "lines" that you can drag manually).

Then, some time after I make all my calls to change each of the 4 manuals, something else appears and sets the “center” again. (I confirmed this with "setCenter" to prove it). The center seems to reset: [UIView (Geometry) _applyISEngineLayoutValues] .

I can’t understand why this is happening, or how to stop it, but this is probably due to limitations. My view is a simple UIButton. When the user clicks on it with a finger, the calling program is called, which simply changes the center. It works.

But in another case, I am raising a UIImagePickerController. After they have selected the image, I define the boundaries of the paper, change the "guide" centers, and then "_applyISEngineLayoutValues" returns them back.

Any idea what happens in this case? Or how can I set a presentation center and actually it will remain?

+4
source share
2 answers

The first rule of AutoLayout is that you cannot directly update the frame , bounds or center tags.

You must update the constraints associated with the view so that the constraints update the view.

For example, the first vertical line will have horizontal restrictions, for example ...

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

This is sufficient (horizontal) to place this line on the screen.

Now, if you want to move this line to the right, you cannot just change the center , you have to do it ...

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

You now have a property indicating this restriction.

Now that you need to “refresh the center” of the vertical line 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]; 

This will update the presentation position and you will not get any errors.

+12
source

You use auto-layout, so the Fogmeister answer is correct, but not everyone can use auto-layout - for example. people who need to support iPad 1 - so I will leave this answer here.

If you need to use a presentation frame, but the system adds restrictions, then there is a workaround; but it’s not very.

_applyISEngineLayoutValues sets your view to center and bounds but does not touch frame . If you override setCenter: and setBounds: to do nothing, and then always use setFrame: in your own code, then _applyISEngineLayoutValues will leave you alone.

I am not happy with this approach, but this is the only way I have found so far to stop _applyISEngineLayoutValues from pooing throughout my layout logic.

+3
source

Source: https://habr.com/ru/post/1480158/


All Articles