Moving Controls in Code

Playing around to see what works and what doesn’t

Ok… in iOS version, there is not the same concept of control bounds as in Desktop Version… as you set Left/Right/Width/Height etc using constraints (which yes I know can be a single value)

but for example… I have two controls, a Canvas and a Button

The canvas is :
height=200
width=200
top=parent.top+40
left=parent.left+40

the button is :
height=30
width=100
top=canvas1.top+20
H.Center=canvas1.centerx

So the button is horizontally centered within the Canvas

Then in the action of the button I put this (oh yeah, I added a MsgBox too)

  messagebox1.message= me.left.ToText+"x"+me.top.ToText
  MessageBox1.show

I click on the button and get 0.00 x 0.00 ’ I would have ASSUMED (and obviously incorrectly) that LEFT and TOP would contain the computed values based on the AutoLayout rule at the instant the button was clicked.

Even more confusing was attempting to add this

me.left=me.left+10  // Cannot assign a value to this property

So does this mean that the controls position is immutable??? and that it cannot be changed (or for that matter even examined at runtime???

If the control can be moved… how it that accomplished in this brave new world?

ObjC/Swift both allow the controls bounds and frame to me changed (with a few exceptions)

alter its constraints
note you can assign a name to a constraint to get easy access to it

Take a look at iOSLayoutConstraint. It is easy to change a constraint once you assign it a name. For example, to change the left offset of a control:


Dim C As iOSLayoutConstraint  =  Self.Constraint("MyLeft")  //  MyLeft is the name of  the 'Left' constraint of some control

C.offset = 50

Ok… so then what good is keeping the properties LEFT/TOP/WIDTH/HEIGHT?
It seems they return a non-zero value if they are assigned a constant value in a constraint, otherwise they seem to return zero

Given a control with constraints, how can you determine at runtime its “realworld” size and location?

Given my above example… how can I determine where the button is in relation to anything else, since button.left returns zero

Moving a control by modifying the constraints is awfully slow because auto layout recalculates everything. Look at https://forum.xojo.com/18110-scrollableview where I posted a project (carre?.xojo_binary_project) made during beta that moves a square on the screen using declares. Then when the moving is done, it sets the constraints again, so Auto Layout finds its marks.

… or you could use the iOSControl extension module where you can set the frame property, alternatively animated, which should work with every visible Xojo iOS control:

https://github.com/UBogun/Xojo-iosLib

[quote=158859:@Ulrich Bogun]… or you could use the iOSControl extension module where you can set the frame property, alternatively animated, which should work with every visible Xojo iOS control:

https://github.com/UBogun/Xojo-iosLib[/quote]

but aren’t the properties LEFT/TOP/WIDTH/HEIGHT read directly from the FRAME?
In Xojo at least those values are ZERO if the constraint is more than a “number”

I don’t know how Xojo handles the properties. I can imagine constraints could give trouble – in the demo I positioned the image without constraints therefore.
On the other hand, when you look at the intro view there’s no problems rotating and scaling the buttons with the animation methods, although they have constraints. Maybe you’d like to give it a try – adding constraints to the imageview with the apple in the bbloc animation view and then animating it. After each animation, the properties are read out and displayed on the screen. Or change one of the button animations in the menu view to a frame animation.

should have been “block” of course, not bbloc :wink:

EDIT: And two functions I haven’t tried yet but implemented are

– TranslateARMaskToConstraints (Boolean): If yes, the AutoResizingMask value is converted into layout constraints.
and

– AutoResizingMask (AutoResizeMask) = If you prefer the old lock properties instead of layout constraints, you can use this property. For creating a Mask, user either Dim aMask As AutoResizeMask and set its properties or call the method AutoresizeMask (ScaleLeft as Boolean, ScaleWidth as Boolean, ScaleRight as Boolean, ScaleTop as Boolean, ScaleHeight as Boolean, ScaleBottom as Boolean) as AutoResizeMask
as well as giving

– AmbigousLayout (Boolean, Read-only) = If true, you should check your layout constraints
together with

– TestAmbigousLayout(): A debug method changing the layout properties of the control when ambigous layout constraints have been detected (see AmbigousLayout property). This makes the control change between the possible positions.
a try. Maybe they can help? Would be nice to know if they work anyway :smiley: