Odd issue (possible bug) with proportional constraints

Hello,

I have an issue with the "Equal Heights Constraint", which seems like a bug in Xcode.

I have created an applicated that requests the user to handwrite several letters on the screen (English, capital letters).

The screen contains 4 image views that are layed out in a 2X2 matrix on the screen.


When I capture the touch events on the view that contains the image views, I draw the line in the respective image view.

The problem that occurs is that the lines get "smudged" on certain types of devices, depending on the contstrains that I have set.

For example if I play around with the multiplier and the constant, it will work fine on all "plus" devices, but will not work on the regular devices.

If I play with the numbers a bit, it will suddenly work fine on 6, 7, 8, ... devices but not on "plus" devices. It looks like it has something to do with the proportions of the screen.


My guess is that the problem stems from the view not regenerating the image properly, making the "redrawing" of the previous image to become blurry while the new lines are added to the image.


If there is a way to add images (making everything clearer) I'd be happy to do so.


Thank you.

Roy

Accepted Reply

It could be due to pixel size, which depends on device.

Try to replace the calls to :

UIGraphicsBeginImageContext(self.tempDrawImage.frame.size);     // The drawing image

by calls to

UIGraphicsBeginImageContextWithOptions(self.tempDrawImage.frame.size, false, 0.0);



in doc:

void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);


Parameters

size

The size (measured in points) of the new bitmap context. This represents the size of the image returned by the UIGraphicsGetImageFromCurrentImageContext function. To get the size of the bitmap in pixels, you must multiply the width and height values by the value in the scale parameter.


opaque

A Boolean flag indicating whether the bitmap is opaque. If you know the bitmap is fully opaque, specify YESto ignore the alpha channel and optimize the bitmap’s storage. Specifying NO means that the bitmap must include an alpha channel to handle any partially transparent pixels.


scale

The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.

Replies

Could you post the code for adjusting constraints ?

What are the plus devices ? 6plus, 8plus, others ?

Hi,

I set the constraints using Xcode, not programatically.

For example, if I set the height of the drawing surface to be equal to the containing view like this:

Equal Multiplier = 0.5 and Constant = -62

It works on iPhone 6 Plus, 7 Plus, 8 Plus

It does NOT work on iPhone 6, 7, 8 (the image gets blurred as I'm drawing)


If I play around with the numbers and change them to this:

Equal Multiplier = 0.49 and Constant = -54

It all of a sudden switches around... it will work on iPhone 6, 7 and 8 but will NOT work on 6 Plus, 7 Plus and 8 Plus.

Other devices are a whole different story, but once I manage to figure it out it will be applicable to other devices as well.


Comment #1: the issue first came up when I tried to build an adaptive layout (without Constants) but could not get it to work. After playing around with the configuration a bit I came across this very bizzare issue.


Comment #2: if I use manual layouts, it works all of the time for all types of devices. This is obviously not very usefull, but that's currently the situation.


The reason I believe it's a bug in Xcode is that there's no real reason why doing such as small change like "Multiplier = 0.5 and Constant = -62" => "Multiplier = 0.49 and Constant = -54" that will cause it to work on one type of devices and not the other.


Thanks for the help, I truly hope you can assist in resolving this.

Roy

Use Xcode’s view debugger to ensure all your view sizes and positions are as you expect at runtime.


Do you have any auto layout warnings in IB or printed to the console at runtime?


How did you arrive at those -62, -54 etc. numbers? You shouldn’t just be entering numbers by trial and error until it “looks right” - in my opinion, adding a hard coded constant like that anywhere is quite fragile. It will very likely break whenever a new screen size / aspect ratio is introduced. Normally you can avoid odd combinations of multipliers and constants, and simultaneously make everything more readable and robust, by using more enclosing views or spacer views. I’m not sure how to explain this better. But normally if you put your two views that should be related inside a single containing view, then size and position that one view using more standard techniques (top, leading, trailing constraints etc.) then everything is more likely to Just Work™.


As Claude says, maybe we will need to see more of the project before fully understanding your issue though.

I have some warnings, but even if I removed all constraints and just added for one of the views (of the total of four views) and the issue still occurs.


The layout that I wish to achive should look like this:

▢▢

▢▢


with a status line above the squares and two buttons at the bottom.

The way I currently achieved it is using one view that contains everything, with "equal width" and "equal height" constraints (I don't need the constants for that matter) and then used "nearest neighbour" spacing to layout the squares top-left, top-right, bottom-left and bottom-right.


Is there another better way to achieve this that would be considered as a "best practice"?

Thanks,

Roy

I am attaching a link to Dropbox that shows the issue:

https://www.dropbox.com/sh/d687nrojwb55gbl/AADxNZ0StjxgD2-w8HyatRAfa?dl=0


One video shows that it works on iPhone 6, the other video shows that it works on iPhone 6 Plus.

The only difference is some minor modifications to the Multiplier and Constant of the "Equal Height" & "Equal Width" constraints.


Any thoughts?

There must be no warnings. If the layout engine is having to guess at things, that would explain your unpredictable results.


I’m on my iPad right now so composing forum posts is painful. When I’m at a keyboard I’ll try and elaborate later on the constraints I’d use for that layout, but in general, the rule is exactly one (no more, no less) constraint for each view’s H and V size and position. Keep things simple.

It could be due to pixel size, which depends on device.

Try to replace the calls to :

UIGraphicsBeginImageContext(self.tempDrawImage.frame.size);     // The drawing image

by calls to

UIGraphicsBeginImageContextWithOptions(self.tempDrawImage.frame.size, false, 0.0);



in doc:

void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);


Parameters

size

The size (measured in points) of the new bitmap context. This represents the size of the image returned by the UIGraphicsGetImageFromCurrentImageContext function. To get the size of the bitmap in pixels, you must multiply the width and height values by the value in the scale parameter.


opaque

A Boolean flag indicating whether the bitmap is opaque. If you know the bitmap is fully opaque, specify YESto ignore the alpha channel and optimize the bitmap’s storage. Specifying NO means that the bitmap must include an alpha channel to handle any partially transparent pixels.


scale

The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.

Thank you Claude!

Changing the call from UIGraphicsBeginImageContext(self.tempDrawImage.frame.size); to UIGraphicsBeginImageContextWithOptions(self.tempDrawImage.frame.size, false, 0.0);

fixed the problem!