iOSLayoutConstraint behaves strange

Hi everybody! I can’t seem to get an iOSLayoutConstraint to work.

This is what works fine:

[code]Dim ctrX As New iOSLayoutConstraint(imgTest, iOSLayoutConstraint.AttributeTypes.CenterX, iOSLayoutConstraint.RelationTypes.Equal, LineField, iOSLayoutConstraint.AttributeTypes.CenterX, 0.46, 0)

ctrX.Active = True[/code]

It sets the imgTest horizontal center to 46% of the LineField horizontal center. The problem is that 0.46 is not static but needs to be calculated. So I’m adding the calculation and replace the value 0.46 with intScale. The variable intLoc is being passed to this method from outside.

[code]Dim intScale As Double
intScale = (100 - intLoc) / 10 * 0.18 + 0.1

Dim ctrX As New iOSLayoutConstraint(imgTest, iOSLayoutConstraint.AttributeTypes.CenterX, iOSLayoutConstraint.RelationTypes.Equal, _
LineField, iOSLayoutConstraint.AttributeTypes.CenterX, intScale, 0)

ctrX.Active = True[/code]

Now nothing happens. The imgTest does not move at all. I thought maybe it’s because intScale has lots of decimals. So I’m doing this:

[code]Dim intScale As Double
intScale = (100 - intLoc) / 10 * 0.18 + 0.1

Dim strTemp As Text
strTemp = intScale.ToText(Locale.Current, “0.00”)
intScale = Double.FromText(strTemp)

Dim ctrX As New iOSLayoutConstraint(imgTest, iOSLayoutConstraint.AttributeTypes.CenterX, iOSLayoutConstraint.RelationTypes.Equal, _
LineField, iOSLayoutConstraint.AttributeTypes.CenterX, intScale, 0)

ctrX.Active = True[/code]
Now I’m getting an exception when I try to create the iOSLayoutConstraint:

NSLayoutConstraint for <UIImageView: 0x116d60880; frame = (305 45.5; 57 38); clipsToBounds = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x6000002497e0>>: A multiplier of 0 or a nil second item together with a location for the first attribute creates an illegal constraint of a location equal to a constant. Location attributes must be specified in pairs."

I have no idea what I need to do. It should work in my opinion but it just does not.

and people wonder why I hate Autolayout :slight_smile:

Now that my Android app is reaching completion with another development tool, I am seriously considering the iOS tool from the same publisher, let alone not to have to deal with an unswitchable auto layout. Besides reusing most of the code, of course.

A good deal of apps today don’t waste time on rotating the display. They simply are portrait only.

My app under Android is Landscape only.

Xojo systematically forcing autolayout is typical of engineers “we know best” attitude.

Even Apple with Swift/Objc does not force the use of Autolayout, and my RAPID Swift UI builder takes full advantage of that

If I see it correctly you added these lines in the crashing example:

[quote=450159:@Christoph Emrich]strTemp = intScale.ToText(Locale.Current, “0.00”)
intScale = Double.FromText(strTemp)[/quote]

You are writing intscale with the current locale (which, judged by your name, could be German, so it uses a comma as decimal separator) and reading it without locale, so it will look for a dot as separator. Did you examine intScale to check if it could be 0? That would explain the “multiplier of 0” message.

Also, I do not see that you used AddConstraint to assign it to imgTest. Did you forget that?

EDIT: And no, the fact that intScale is not rounded does not influence its functionality. You can safely remove that code again and retain precision.

I did not use AddConstraint because it’s not used in the Xojo Example project either. When I use AddConstraint for imgTest, the simulator shuts down and Xojo stops debugging without any kind of error message.

It’s really driving me crazy…

Now I’ve tried something else. I created a layout constraint in the Auto-Layout (not in the code) and assigned a name “TestPosition”. So now I just have to change the scale, right?

[code]intOffset = (100 - intLoc) / 10 * 0.18 + 0.1

Dim c As iOSLayoutConstraint = Self.Constraint(“TestPosition”)
c.Scale = intOffset[/code]

Nope. Error message is that I cannot assign a value to the property Scale. This is nuts…

its hard to tell for sure with that tiny bit of code
the error message would lead me to suspect that intScale is 0
or linefield is nil

fixed positions are easy to do in autolayout FWIW
wouldnt even surprise me if under the hood fixed positioning is done that way using autolayout :slight_smile:

This is not nuts but clearly by design: iosLayoutConstraints are immutable; you cannot change their properties after creation. You have to replace the constraint with another one instead.

This is, btw., not a weirdness of Xojo but Apple’s design. See multiplier | Apple Developer Documentation

@property(readonly) CGFloat multiplier;

[quote=450283:@Norman Palardy]fixed positions are easy to do in autolayout FWIW
wouldnt even surprise me if under the hood fixed positioning is done that way using autolayout :)[/quote]
except that Left/Top are readonly meaning you cannot say

ctrl.left=250

not to mention even Xojo AL restricts some other values, such as height (makes sense of UISwitch, but not UITextField)

you can make an autolayout constraint that makes a control behaves as though it has absolute positioning

set its left to the overall view containers left + a fixed offset

and you can alter the constant offset whenever you want
https://developer.apple.com/documentation/uikit/nslayoutconstraint/1526928-constant?language=objc

this is why it would not surprise me if apple under the hood uses autolayout regardless

My deepest regret is that there is no “manual” positioning, analogous to what XCode provides, where when I move a control in the IDE, Xojo does not try to guess relatives to.

In a true fixed positions visual layout editor, controls are always relative to left and top, instead of changing to relative to other controls.

[quote=450294:@Ulrich Bogun]This is not nuts but clearly by design: iosLayoutConstraints are immutable; you cannot change their properties after creation. You have to replace the constraint with another one instead.
[/quote]
Well, you can change the offset, not the scale though. But how do I replace a constraint? I am using the exact same code that’s being used in the sample project “LayoutConstraintExample” and there it works every time. I mean, all I want to do is move an image a few times. That should certainly be possible.

To replace a constraint, you must set it as active=false and add a new constraint.