Obj-C, changing autolayout at runtime, woes - ios

I'm trying try hide table view and move a button up the screen, which is different to my autolayout setup. Basically, I have a free version of my app where I hide things, then if they purchase I need to set the constraints back to those in interface builder.
I have a similar question open, but I think I'm fundamentally flawed in my approach.... (I've taken the advice of something who provided and answer, asking this separate question).
ObjC, revert to interface builder autolayout constraints, after adding / removing programmatically?
I can move things up fine, which modifies my interface builder constraints.
But, when the user clicks upgrade, I cannot then set the modify they again / constraints back.
No matter what I do, use visual format language at runtime, or use NSLayoutConstraint constraintWithItem outlets to copy and then modify my constraints it doesn't change. I've tried removing constraint outlets, copying those I stored at viewdidload and remove vfl constraints, exact copies of those which I added for my free version.
I was getting some vfl warnings, until I added priorities.
Is there somewhat I can dump out the vfl for everything and try and figure out the problem or can something suggest the why the approaches I have tried have failed?

Instead of attempting to replace and restore constraints at runtime, consider setting up all the constraints you will need in Interface Builder, with references to those which are state-dependent. Then, when state changes according to your own logic, activate the state-appropriate constraint(s) and deactivate the inappropriate ones. NSLayoutConstraint has an active property, which determines whether it is used for laying out its view.

Related

NSLayoutConstraint "installed" property in Interface Builder

Is the "installed" property only for enabling/disabling constraints for different size classes and not for runtime changes?
I want to have multiple sets of constraints that I enable/disable based on some condition on a view inside an UITableViewCell.
But if I design them all in IB and uncheck installed for some of them and then try to activate/deactivate them during runtime, nothing happens. I am storing strong references and I have tried numerous setNeedsDisplay/setNeedsUpdateConstraints on the different views.
The only way to make it work is to have all of them installed and the extra ones be with priority of 999, to avoid errors. Then I can activate/deactivate them during runtime with no problems.
You should use the isActive property. Remember to do this on the main thread by using DispatchQueue.main.async{ ... }
You can activate your constraints if you have an IBOutlet for each one of them.
You need to be carefull though and disable those that will conflict before activate your constraint otherwise it will fail, that most likely is your issue.

How to disable "Relative to margin" option for newly created constraint in Xcode6

I want to disable automatic adding Relative to margin when creating constraints in IB of Xcode 6.
It's nice that they turn this option on by default, but I have to support iOS7, so it turned out I have to manually disable this option every time after adding new constraint.
I found this setting for disabling it beforehand, but it's always on by default.
The closest I've ever come to this is hacky at best, so take this for what it is...
Creating AL constraint while not holding Option:
Creating AL constraint while holding option:
In IB if you hold Option while creating the AL constraint, it toggles whether the constraint binds to a margin or not. That's one convenient way to avoid re-editing the constraint. Further (and this is the hacky part because I can't explain it) I've noticed that in projects where I start holding option and binding AL constraints without the margin, that behavior becomes the default!
Like I said, it's hacky and I can't explain it why the default changes sometimes, but holding Option when you create constraints is the closest I've ever gotten.
This plugin will set a default value of Constrain to margins to disabled.
https://github.com/mshibanami/DefaultMarginDisabler
It is by default enabled in storyboards, I have not found how to disable it.
But in Xibs, it is unchecked when you create a constraint.
A solution may be to create a storyboard that instantiates your xibs, but you will loose every possibilities given by the segues.
So You may want to deal with it since there's no option for that (so far... ?).

Missing Constraint Autolayout Warning

I have a project and I used to add constraints with xcode interface builder. In a specific case I needed to add some constraints in my controllers source. My question is that although I have the result I was seeking for, xcode returns missing constraints warnings.
Is this something I should handle? I mean, I add constraints in the source code. Show I do something to update my storyboard in order to be aware of these?
You don't need to handle these, but if you want to get rid of the warnings, you can add placeholder constraints in IB, that are removed at build time, so you can replace them with code generated constraints. When you select a constraint, and go to the Attributes Inspector, you will see a box, "Placeholder -- Remove at build time". If you check that box, those constraints are automatically removed.
No,you dont need to , if you have added constraints in the source code than it will be executed during runtime. so you dont need to handle those warning only if you have added those constraints in the source code.
AutoLayout is a descriptive "language" which describes how the layout should be rendered (frames size, spacing etc.) into the view during the runtime. When you have missing constraints warning, in other words ambiguous layout,there is a good chance that the layout will have unpredictable behavior. In order to make sure that your layout is rendered as you wish, you should clear these warnings.

Views disappear when `translatesAutoresizingMaskIntoConstraints` set `NO`

Problem
Some third party library is used. Some views disappear after their translatesAutoresizingMaskIntoConstraints are set to NO.
Don't have other autoresizingMask setting for my views in my own code; in the library, the autoresizingMask parts of code have been removed too. Instead, explicit bounds/center/frame are set for those views. There're no nib files, views are all programmatically created.
I know some other people solve similar problem by giving a thorough autolayout constraints set, but in my case, I mean to turn off autolayout and do it manually. No idea when autolayout is turned on.
Some people say that "by default, as your app launches, autolayout is switched off, and the system behaves as in iOS 5 and before. But if, at any time while your app runs, the system sees an autolayout constraint (generated in code or by the loading of a nib that has “Use autolayout” checked), the autolayout system is switched on, and from then on you’re running under autolayout." (Programming iOS 6 by Matt Neuberg, pages 383-384), but in my project I don't think there's any autolayout constraints left.
The code is bulky, but will upload some skeleton if necessary.
Thank you for tips!
If you don't want to use Auto Layout you have to set translatesAutoresizingMaskIntoConstraints to YES. Here's a reference:
This works through the property
translatesAutoresizingMaskIntoConstraints. When this property is YES,
which it is by default, the autoresizing mask of a view is translated
into constraints. For example, if a view is configured as in Figure
6-1 and translatesAutoresizingMaskIntoConstraints is YES, then the
constraints |-20-[button]-20-| and V:|-20-[button(20)] are added to
the view’s superview. The net effect is that unaware views behave as
they did in versions of OS X prior to 10.7.
For views that are aware of Auto Layout, in most circumstances you
will want translatesAutoresizingMaskIntoConstraints to be NO. This is
because the constraints generated by translating the autoresizing mask
are already sufficient to completely specify the frame of a view given
its superview’s frame, which is generally too much. For example, this
will prevent a button from automatically assuming its optimal width
when its title is changed.

Where is the Xcode checkbox "Translates Autoresizing Mask Into Constraints"

In one of the WWDC 2012 videos, Auto Layout By Example, they demo an OS X app using Autolayout, and at about 7 or 8 minutes in, he shows how for a single view, you can uncheck a box in the Attributes Inspector, and the box is called something like "Translates Autoresizing Mask Into Constraints". Now, I'm well aware of the code equivalent of this box, the translatesAutoresizingMaskIntoConstraints boolean, but I can't seem to find this checkbox anywhere in either iOS or OS X projects. My project uses Autolayout. I really would like this checkbox, because one of things I'm struggling with in learning Autolayout (and converting a springs/struts app to AL) is the million constraints Xcode has generated for each view, and how to clean them up and sensibly override some/all in code. What I'd like in order to do this conversion one view at a time is to turn off those auto-generated constraints.
Why can't I see this checkbox? I'm using Xcode 4.6.
That checkbox is available in Interface Builder (IB), but only if you are developing Cocoa projects targeted for OS X. For iOS, it's not available at present. You can only set it programmatically.
Auto Layout on iOS from my understanding - and others feel free to pitch in here - is not a full implementation of what is available on OS X.
To be honest, given what you say afterwards, this checkbox is probably something you don't need to worry about. I think it is important in upgrading OS X projects to Auto Layout, but generally for iOS it's unlikely you'll be mixing one and the other. I.e., you either checkbox your Xib in the File Inspector to "Use Autolayout" or you don't.
That said, there is one use case where you may need to mess with that flag. That's if you want to create a standalone Xib file for a view, and then load that programmatically using loadNibNamed. When doing that, by default old style Auto Resizing constraints are converted into new style Auto Layout constraints. Typically I want to add my own so I set that flag to zap 'em.
myView.translatesAutoresizingMaskIntoConstraints = NO
Anyway that's another story.
Here's the link for more info, although you've no doubt had a look at it already:
Adopting Auto Layout
One thing I'd say is that if you're struggling with Auto Layout in the beginning - and you wouldn't be human if you weren't, we all have been - then I'd stick with Interface Builder and think about the golden rules. The most important one for me is that it hates ambiguity. It's like a vacuum in nature. Before you can delete the constraint that you don't want, you have to add the one that you do want then zap the old one.
The other mistake that I made was mixing Auto Layout and frames. So I'd do some code that checked the frame width then apply that to the constraints. Bad mistake. That really ends in tears. When you get into Auto Layout it's essential to really forget about doing anything with CGRect, frame, etc.
Stick with it though. Start with some simple views in IB and experiment. There is method to the madness, really.
One more link also worth looking at is:
10 Things You Need To Know About Cocoa Autolayout

Resources