iOS: Button menu with autolayout - ios

I came across the project: https://github.com/monoqlo/ExpandingMenu
which adds a button to a view. when the button is added a menu appears. You can find details behind the link.
The problem is that this project doesn't support autolayout and all frames are hard coded. So it doesn't support device orientation changes.
Currently I'm trying to rebuild it with autolayout. How would you do it?
Start with a xib?
Doing everything hard coded?
Do you know some code that could be reused?

Maybe you can try these:
First: check out the code of ExpandingMenu, I know it hard code, that is to say, it use the frame of its superview or [UIScreen mainScreen]'s frame. Make clear when it set its subviews frame.
Second: first may have 2 options
one is setting its subviews frame when it init or added in view: In this case , you have to rewrite it or else, in a word , you can not use it to support device orientation.
one is setting its subviews frame when it calls layoutSubviews: In this case ,it is able to support device orientation.
That is to say: if it does not support device orientation, you can fix it by rewrite it to make it setting in layoutSubviews.

Related

Custom interfaces for Portrait & Landscape mode iOS

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.

Designing without auto layout so that it works for every size device

I'm designing an iOS app in Swift, not using auto-layout. I'm not using auto-layout because if i do, when my labels update, the design resets. For now, I'm designing for an iPhone 4.7 inch, but when i run it on the simulator for any other size device, the design is completely messy.
UPDATE:
I designed my storyboard with the proper constraints. I added my UIImages in the override func viewDidLayoutSubviews and positioned them outside of the screen. When a button is tapped, there should be a sequence of animations which are triggered as well as a UILabel which should have its value updated.
I commented out some code and kept running it to find the problem, and I found that the UIView reset whenever the UILabel updated. The values are being queried from Parse.com.
The design works when the label is NOT being updated. But once the value changes, the view resets...
I tried disabling auto-layout and it works. However, if I have auto-layout turned on it doesn't.
What do I do?
Thanks in advance
You should really use Auto Layout. It is the way forward for UI layout. The problem with your labels can surely be fixed with proper constraints.
Make sure you modify constraints instead of frames. The layout engine will calculate the new frames when needed, as helpfully mentioned by #rdelmar.

On orientation change touch events recognized for half the screen(portrait width)

I have a PageViewController which handles the gestures so I have not done anything with it. I disabled auto-layout in my storyboard so that I could use autoresize to fill the screen with views.
I have a tabbar and if I reload the page with the tabbaritem. The gesture are working.
How can I make the touch/gesture handler resize on orientation change?
http://kevindew.me/post/18579273258/where-to-progmatically-lay-out-views-in-ios-5-and
In the above link you will find usefull information about laying out and handling orientation changes. Also I had this problem once on a device with lower iOS version if your version can be updated you can try that however it's not a fix. I recommend to check the link and see if your views are properly layed out.

Handling interface rotation in iOS 7

Very simple question, but I'm asking as there seems to be a lot of conflicting views and I've been completely unable to find a definitive answer, let alone a modern one.
I use Auto Layout for 99% of my handling of the user changing from portrait to landscape or vice-versa in a UIViewController. Works great. But sometimes, I have to rely on frames still for one reason or another.
How would I best handle this?
You have willAnimateRotationToInterfaceOrientation, willRotateToInterfaceOrientation, the NSNotification methods with checking status bar, and I'm sure there's some others.
If I want to change the position of a view when the user rotates, which method should I be changing the frame in? And is it best to do it with a simple setFrame: or should I be using autoresizing masks?
Since iOS6, you should not be using willRotateToInterfaceOrientation: and didRotateFromInterfaceOrientation:. These are only called on the front-most presented view controller, and will not be called on others. This means if you have a pushed view controller or a presented view controller, all others will not layout correctly.
Instead, you should always use viewWillLayout and viewDidLayout to handle rotation. They are both called inside an animation block, so anything you do which is animatable, will be animated.
For positioning views, you can either set the frames yourself, or use auto-layout constraints and adjust the constraints in viewDidLayout. If you go the auto-layout route, never remove and add constraints. Use the same constraints as much as possible and just adjust their constant values.
When I'm changing the main view frame, I typically adjust the frame in willRotateToInterfaceOrientation if I need to. Then I adjust any subviews by overriding layoutSubviews for my main view.
I don't know that this is a definitive answer, though - I don't think there really is a definitive answer - it depends on how your application is structured.
wilLRotateToInterfaceOrientation and didRotateFromInterfaceOrientation are best used for stuff you need to do before and after rotation, respectively (for example, disabling user interaction before the rotation begins, and reenabling it after). Everything else should be done in layoutSubviews if possible.
Autoresizing masks are useful sometimes, but I usually lay everything out manually to avoid any surprises when things change between iOS releases (as they often do).

UIImageView not rotating when device orientation changes

I have a VC with two imageViews. One takes up the whole screen, the other is actually slightly larger and can be moved around on the screen (Pan Gesture).
When the device changes orientation only the static view changes orientation, or just updates its frame maybe (automatically).
The second Pan UIImageView does not move. Is there a reason for this, or a switch to make this happen somewhere possibly in the storyboard properties of the UIImageView itself? I would like the view to move too.
I understand that an option would be to use the methods that confirm the orientation has completed a change and transform the imageView myself, which is not a problem... but checking I am not missing something that could do this for me automatically first.
Ensure you are using correct AutoResizeMasks on the imageview. Provide your code or storyboard description for a more complete answer.
-Additionally if you are using AutoLayout, you may need to add the appropriate constraints (making it slightly larger than the view may confuse it as to your intention without proper suggestions via constraints).

Resources