Constraint Crash

  1. 8 weeks ago

    Jon O

    Feb 12 Pre-Release Testers, Xojo Pro Chicago Area USA

    Hey all,

    I'm struggling with the fact that adding a constraint to my app is causing the app just to quit in Xojo with no explanation. Here's the situation:

    1.) I have a 5 controls that I want to evenly space across the display.
    2.) I have these set up with both width and left constraints in the IDE. It seems like if you don't have constraints initially in the IDE it's nearly impossible to even attempt to place controls on the screen as they do very bizarre things. Right now the first control on the left side is tied to the left of the view with a fixed offset.
    3.) I want to calculate both the widths for each control and set that as well as set the left position of the first control based on the width of all the controls so that the controls are all centered.
    4.) When the program starts, I remove the width constraint in the open event of each control. Code in the parent subclass for the control then sets a new constraint and the width by setting an offset. This works fine.
    5.) I then attempt to set the left value of the first control by removing the left constraint and adding a new constraint. As soon as I apply the new constraint, the debugger just quits. Silently fails. The app still appears to be running in the simulator and I have to reboot the simulator device in order to be able to continue working. Here is my code:

    Me.RemoveConstraint(Self.Constraint("MyLeft"))
    
    Dim TheLeft As iOSLayoutConstraint
    
    TheLeft = New iOSLayoutConstraint(Me, _
    iOSLayoutConstraint.AttributeTypes.Left, _
    iOSLayoutConstraint.RelationTypes.Equal, _
    Me.Parent, _
    iOSLayoutConstraint.AttributeTypes.Left,1,0,1000)
    
    Me.AddConstraint(TheLeft)

    What I am doing wrong? For the reference control I've tried self, me.Parent, View1, etc. All result in this crash. I've change relationship types around. Still the crash.

    What is going on?

  2. Jeremie L

    Feb 12 Pre-Release Testers, Xojo Pro, XDC Speakers, MVP Europe (France) - packr.app
    Edited 8 weeks ago

    Crash logs are located in this folder on your Mac:
    ~/Library/Logs/DiagnosticReports/

    Assuming your code is in an iOSView, not in a control subclass, this should work.

    self.RemoveConstraint(Self.Constraint("MyLeft"))
    
    Dim TheLeft As iOSLayoutConstraint
    
    TheLeft = New iOSLayoutConstraint(Me, _
    iOSLayoutConstraint.AttributeTypes.Left, _
    iOSLayoutConstraint.RelationTypes.Equal, _
    self, _
    iOSLayoutConstraint.AttributeTypes.Left,1,0,1000)
    
    self.AddConstraint(TheLeft)
  3. Jon O

    Feb 12 Pre-Release Testers, Xojo Pro Chicago Area USA

    Here's what the logs say:

    Application Specific Information:
    *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. constraint:<NSLayoutConstraint:0x60c000080870 XOJCanvasView:0x11480f770.left == UIView:0x114c07260.left (active)> view:<XOJCanvasView: 0x11480f770; frame = (20 74; 177 286); opaque = NO; layer = <CALayer: 0x60c000023000>>'
    terminating with uncaught exception of type NSException
    abort() called

    So I'm not sure why it's doing this. The code is in the open event of the control.

  4. Jeremie L

    Feb 12 Pre-Release Testers, Xojo Pro, XDC Speakers, MVP Europe (France) - packr.app
    Edited 8 weeks ago

    As I explained in another thread, constraints are to be added to the parent/containing View or Control.

    You should set the Left constraint in the view, not the control itself.

    In the view open event this should work

    Dim cons As iOSLayoutConstraint
    
    //Left
    cons = New iOSLayoutConstraint(theControl, _
    iOSLayoutConstraint.AttributeTypes.Left, _
    iOSLayoutConstraint.RelationTypes.Equal, _
    Self, _
    iOSLayoutConstraint.AttributeTypes.Left, _
    1.0, 0, 1000)
    Self.AddConstraint(cons)
  5. Jon O

    Feb 12 Pre-Release Testers, Xojo Pro Chicago Area USA

    @Jeremie L As I explained in another thread, constraints are to be added to the parent/containing View or Control.

    You should set the Left constraint in the view, not the control itself.

    In the view open event this should work
    Dim cons As iOSLayoutConstraint //Left cons = New iOSLayoutConstraint(theControl, _ iOSLayoutConstraint.AttributeTypes.Left, _ iOSLayoutConstraint.RelationTypes.Equal, _ Self, _ iOSLayoutConstraint.AttributeTypes.Left, _ 1.0, 0, 1000) Self.AddConstraint(cons)

    That doesn't make sense. Why then does every control have an AddConstraint method? And I can add the width constraint in the custom subclass of the control and it works perfectly.

    Is it because it is being tied specifically to the View in this case?

  6. Jeremie L

    Feb 12 Pre-Release Testers, Xojo Pro, XDC Speakers, MVP Europe (France) - packr.app
    Edited 8 weeks ago

    Because each control can be the container for another control.

    Layout constraints are always layed out but the containing view in relation to all other controls displayed in the view.

    In order to define a width from within a control, you could raise an event with the new constraint or just the width and make sure to add the appropriate constraint in the event handler on the iOSview.

    This isn't Xojo doing something wrong, it is how the iOS system works.

  7. Jon O

    Feb 12 Pre-Release Testers, Xojo Pro Chicago Area USA

    @Jeremie L Because each control can be the container for another control.

    Layout constraints are always layed out but the containing view in relation to all other controls displayed in the view.

    In order to define a width from within a control, you could raise an event with the new constraint or just the width and make sure to add the appropriate constraint in the event handler on the iOSview.

    This isn't Xojo doing something wrong, it is how the iOS system works.

    Adding the "width" constraint in the subclass code works quite well. I just have to have it execute after the control is already opened. But my secondary control is NIL so perhaps that's why it works....

or Sign Up to reply!