I have an app which has a different UI for portrait and landscape. I've heard wonderful things about Auto Layout but in all my readings it seems to handle simple cases, where UI widgets resize and reposition simply. In my UI UI widgets move. Is this a case where I should try and get auto layout to work or should I just make 2 xibs and be done with it?
You can see in the portrait version that the green element is below the magenta one, but it is above it and next to the orange one in the landscape orientation.
Sorry, one auto layout setting will not allow you to rearrange views like that. You could still use auto-layout for positioning and spacing, but you'll need two sets of settings.
You could still use one xib file and change the auto layout settings at run time, but most likely multiple xibs makes more sense because you'll be able to see and edit your UI WYSIWYG style.
Update
Also, take a look at iOS 9's new UIStackView.
Related
I am trying to layout user interfaces differently for Portrait & Landscape orientations. The difference comes in the following ways:
I have few UIStackViews. Some of their axis becomes horizontal in landscape but vertical in portrait mode,
The order of buttons in UIStackView may be different in both the modes,
A button which is added to subview1 in landscape needs to be removed & added to subview2 in landscape. subview1 may not be present at all in portrait mode,
Autolayout constraints are different in both the modes.
I started with vary for traits in XCode but it seems to have limitations. I am manually switching constraints in the code on observing trait collection changes (viewWillTransition:...) but it seems clumsy. Is there a better way or the best way would be to have duplicate sets of controls for both the modes and hide the ones not needed in landscape/portrait modes?
The interface builder is really powerful if you use it right, I'm not completely sure what you're trying to do, it'd be useful if you share some screenshots at least. I'm assuming that you're every subview of the UIStackView is a button, or it contains a button, in that case what I'd do is:
Having 2 different UIStackView, one for landscape and the other for portrait.
Add variants to the installed interface builder property for traits. So only one of the two UIStackView will be installed at a time.
For every UIButton add the event, connect it to the respective IBAction or selector. This will work even if there're 2 buttons that do the same.
So regarding your issues:
The axis itself wont change, but this will work because there're 2 version of the UIStackView.
You can choose to arrange the button on each UIStackView.
Just add the buttons wherever you want on each UIStackView.
Set the constraints as you want depending on which UIStackView you're working on.
An I missing something? please update your question with more information so people can help you in a better way.
What I have done is to observe the UIDevice.orientationDidChangeNotification and update the necessarily constraints to achieve different layouts, as you have already implemented. And I think this is the better way to solve the problem and never trying or even thinking to create different views for each orientation 🙅🏿♂️.
Attending the conditions:
The first condition only needs to set the axis property accordingly.
The order of the arrangedSubviews is part of the design, and therefore, its up to the developer to rearranged them manually if he/she has to.
In this part what I would do is what you have said: to removeFromSuperview() the button and addSubview(view:) from one subview to another.
This is made automatically, as long as we activate the constraints for one orientation and deactivate the other ones, the system update the UI without any problem.
The most important thing is to make sure that when removing subviews, any constraint attached to it is removed, or the app will crash.
I have been creating an application for iPhone and iPad. I am using Auto Layout (wAny and hAny). Now I want a separate design for iPhone 4s alone. How can I use separate designs for this device. I already completed most of the designs with this wAny and hAny. How can I change this.
Edit:
I want to change only few view controller not all the designs.
I suggest not to go with different storyboards. You can add 2 views inside that viewcontroller's(for which the design is different) view and toggle it programmatically depending on the device. Regarding autolayout, set wAny and hAny and add constraints accordingly.
VC.view
-iPhone 4 View
-Other device's view
This can be done in storyboard only.
So programmatically when loading the vc, check the device and show the specific view hiding the other view. In this case in future, even if the design is normalized, you can easily use the same view with change in one line of code.
This is necessary if the design is totally different. Or if it's just few sub views which are different, I think you should write some code to hide and unhide the subviews acc to the device.
I am a novice in iOS, please correct me if I am wrong anywhere.
Better to go with design it as separate controls if you have design changes and load it conditionally for 3.5 inch screens . If its a simple changes (easily managed through codes) then go with codes itself.
I have already developed an IOS app in Objective C, Xcode 6 in which I have disabled the auto layouts and size classes.
Is it now possible to use auto layout after having disabled it earlier?
If yes, how can I implement it? When I enable the auto layouts and size classes and I implement the constraint on the label, the background colour of the label changes to white. When I do this for other object types, they become invisible.
To answer your first question, yes: it is indeed possible to use Auto Layout in an app after having disabled it. Each Xcode project template just gives you an initial starting point – nothing is set in stone.
For the second question, the best way of implementing Auto Layout in an app is to just take it one view at a time. You don't need to go all-or-nothing with Auto Layout; it's possible to just use it in certain cases but use frame based layout in others. Start on smaller, easier views and go from there.
The last issue around background colors is a little trickier without having screenshots or code samples. I have had views disappear on me after implementing Auto Layout and the issue always boiled down to bad constraints. The best solution I can give there is to just do the usual view-debugging work (as in, printing frames and manually setting bright colors to see where views actually are) and figure out what is going wrong.
Having the background color change to white is interesting, though... Auto Layout should not be affecting that at all. It sounds like the background color got changed somehow while the constraints were being created.
I want to embed UIScrollViews in my UITableViewCells in order to accomplish the iOS 7 cell sliding paradigm (seen in Mail.app among others).
I normally set up the entirety of my app in Storyboards and use Auto Layout. UIScrollView is unfortunately very annoying to use in conjunction with Auto Layout, so I guess I'm going to have to avoid using it.
What's my best course of action for using UIScrollView with a Storyboard that uses Auto Layout? (I need the scroll view to adapt to a landscape orientation switch, something that would be very easy with Auto Layout.) I still would like to use Storyboards, and need to position the scroll views, but as I can't just switch to strings and struts for one view, and Auto Layout is out, I'm rather stuck.
Should I create its size in portrait, not set any constraints, and then in viewDidLoad set some auto-resizing masks? Or is it only zooming that UIScrollViews and Auto Layout conflict over, and simple panning should be fine?
See http://www.teehanlax.com/blog/reproducing-the-ios-7-mail-apps-interface/ and an implementation using autolayout at https://github.com/Jafared/JASwipeCellExperiment.
Courtesy of jafar's comment on Swipe to Delete and the "More" button (like in Mail app on iOS 7).
I want to minimize the amount of code I have to write, and use storyboards in xcode to specify the way the view should appear when in both portrait and landscape views.
What is the best/recommended way to do this that minimizes code? I've done some research, but am having trouble finding a simple solution..is it necessary to do some conditional segues, and re-hook up everything in my landscape view, or is there a simpler solution? Thanks!
Generally you define the autoResizingMask (or go to the size inspector in Interface Builder, as shown below) so that the controls will move or resize as the screen size changes. If you do that, you'll generally have pretty decent support for both landscape and portrait. You'll only have to do programmatic changes to the controls' frames if you do some fairly significant changes on orientation changes (e.g. you want to shuffle the various controls around so that they are in very different positions with respect to each other when you change orientation or you want to load very different UIImages). But 90% of the time, autoresizing settings can handle simple moving/resizing/recentering of controls for you: