1

Here is some puzzling issue related to constraints in an iOS app.

The code is:

        view.addConstraints([NSLayoutConstraint(item: infoLabel,
                                                attribute: .centerX,
                                                relatedBy: .equal,
                                                toItem: view,
                                                attribute: .centerX,
                                                multiplier: 1.0,
                                                constant: 0.0),
                             NSLayoutConstraint(item: infoLabel,
                                                attribute: .top,
                                                relatedBy: .equal,
                                                toItem: iconView,
                                                attribute: .bottom,
                                                multiplier: 1.0,
                                                constant: 50.0)])

The code above is executed when in portrait mode. The constraints used for landscape mode being irrelevant for the present question I do not include them. On an iPhone 6 with iOS 10.2.1 it works perfectly. The problem is on an iPhone 4 (3.5 inches) and on an iPod Touch (4 inches), both with iOS 9.3.5; the first constraint (with .centerX) does not work.

More precisely, the problem appears when rotating the device coming back from landscape mode, the centering is no longer performed as expected. In other words, it is working fine when displaying in portrait mode at start. I wonder if there could be a miss in my code or if this is due to a difference of iOS versions or a difference of devices.

Additionnal information: Constraints used in landscape mode:

        view.addConstraints([NSLayoutConstraint(item: infoLabel,
                                                attribute: .right,
                                                relatedBy: .equal,
                                                toItem: view,
                                                attribute: .right,
                                                multiplier: 1.0,
                                                constant: -30.0),
                             NSLayoutConstraint(item: infoLabel,
                                                attribute: .centerY,
                                                relatedBy: .equal,
                                                toItem: view,
                                                attribute: .centerY,
                                                multiplier: 1.0,
                                                constant: 20.0)])

And before those constraints are set, this line of code is executed:

view.removeConstraints(view.constraints)
Michel
  • 10,303
  • 17
  • 82
  • 179
  • Maybe the landscape constraints don't matter for the issue, but certainly the code that deactivates/activate *when rotating the device coming back from landscape* does. Could you post that - and possibly the relevant landscape constraints also. –  Feb 04 '17 at 07:05
  • Thanks. For both orientations some constraints are missing - namely, height and width (be they intrinsic, defined in IB, or coded). Is infoLabel a different size when started in portrait versus landscape? And if so, does it appear the infoLabel retains it's landscape size when rotated back to portrait? –  Feb 04 '17 at 07:20
  • OK. I may have forgotten some of the constraints in the post. Again I have tried to put what is relevant to the question. But still my code is working like charm on the iPhone 6 (iOS 10.2.1) and infoLabel is not X centered on the other devices(as mentioned in the post) as it should. I can add more code or information if you think it is necessary. But I am not sure it is needed. The question is to know if my code is the problem or if there is a diifference due to versions, or devices. – Michel Feb 04 '17 at 15:34
  • Hard to say. My app uses constraints (anchor-based) in code, almost nothing in IB, is universal (iOS9+), and has both portrait and landscape layouts. No issues on any models. My basic layout uses a GLKView with 4 sliders below (in portrait) or to the right (landscape). Constraints are maintained via arrays that are activated/deactivated (unlike yours', which are removed from the view). That's about as descriptive as I can get without a code dump. I *do* use center X/centerY, NSLayoutGuides for some spacing, width/height.... So you can see, it's hard to help much more than I have tried. –  Feb 04 '17 at 16:24
  • @dfd You (at least indirectly) put me on the right track. Reading your comment made me look into the activate/deactivate thing which I had never done before. I have to say, it works and finally solved my problem. I still do not quite explain why it was not fully working before though. But if I can find the time I'll put some sample project together to show the issue and put it on GitHub. – Michel Feb 07 '17 at 01:47

0 Answers0