Custom input views: how to prevent them from fading during orientation change? - ios

I am having trouble with assigning a UIControl subclass I made as a text field's inputView.
It shows - as expected - when the text field becomes firstResponder and hides when it resigns it firstResponder status.
However, the thing I am having trouble with is handling different orientations:
I set an autoresizingMask to the control's subviews so that there is a smooth transition when changing its width.
The thing is, they appear to be ignored as soon as I set it as the inputView.
When enabling the simulator slow-motion animations via triple-hitting shift, you can see very clearly that the view fades between the two states.
This is not what I want. Firstly it looks odd, and secondly this does not fit my needs.
Since the inputView contains a UIScrollView-like element, it would stop its deceleration animation during the fade.
Now my question is: Is there a way to prevent the fade from happening?
I would really like to use the inputView property since it saves me from writing lots of lines of code.
Also, is it possible to specify different heights for different orientations?
Here are two demo projects showing how it is and how I want it to be.
Thanks in advance.

You can create a method to your DatePicker class, that changes the geometry and layout of the view for different orientations and the implement the method
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
in your view controller and call the method on your view to align it.

Until today I have found no way to prevent them from fading.

Related

Custom Keyboard Accessory view input

I have created a custom accessory view to supplement the standard Apple alpha iOS keyboard.
The purpose is to add a line of numeric keys to prevent flipping back and forth between keyboard views. At first, I created a toolbar and loaded it with a set of 0 - 9 titled buttonItems and it functioned quite well. However, it looked terrible, not at all like the alpha keys despite adding a rounded rect background image to each key because the system apparently prevents customizing font size and button spacing inside the stack view of the toolbar. Therefore, I created a UIView xib and loaded it with a stackView full of customized numerical buttons. When I add the UIView as the accessory view it looks pretty darn close to the rest of the Apple Alpha keyboard. The issue now is that the touch-up events go to the UIView class of the accessory view. Is there a clever, efficient way to have the button presses in the accessory emulate the std keyboard feeding into TextField: shouldChangeCharactersIn? I could package the button presses into a local notification event to get it into the class holding the textField but that seems terribly inelegant! Any suggestions would be greatly appreciated. Stay Safe!
Not the best answer, but I did implement notification on key button press with an observer in the main view class. The observer does a TextField.insertText which is suboptimal since I will need to refactor the several hundred lines of code that performs real-time language translation in the shouldChangeCharacters methods. Ah well.

Who should manage the UI Elements, the view or the view controller?

I am currently developing an iOS app and I was wondering how to manage the UI elements. I am using a Storyboard to place my views and Autolayout to make everything resolution independent. If it helps, here's a bit of background on how I came up with this question.
Some Backgroud
I have buttons the represent piano keys and I later in code add a subview to these that draws the actual keys on them. I did this by creating #IBOutlets on the ViewController and susbscribed to the UIDeviceOrientationDidChangeNotification. This called a method that adds the subviews based on the current button frames to get the appropriate sized keys.
This worked fine when running in iOS 8.1, but if I ran the app on iOS 7, the frames of the buttons weren't updated to the new orientation by the time I got the UIDeviceOrientationDidChangeNotification, so everything was messed up in landscape. I did a little research (UIInterfaceOrientation not yet updated when UIDeviceOrientationDidChangeNotification caught in UIView) and it seems that a good solution would be to override the layoutSubviews method. Problem is, layoutSubviewsis a UIView method, and I am managing my buttons and UI in my UIViewController.
Impulsively I wanted to subclass my UIView, override layoutSubviews and from there call a method on my Controller to add the keys to the buttons correctly, but that doesn't sound right.
The Questions
My UI is managed by the UIViewController. But I need to update my views based on a method proper of a UIView. I assume, to respect the MVC principles, that my view should't now a thing about my controller, but then this brings up a few questions:
Who should be managing the UI?
Is my strategy wrong and should the
UIView hold the #IBOutlets to the buttons so that it can later
apply the subviews I need them to have?
If you read the background, do you have a suggestion for this particular situation?
I assume the complexity of this problem is relatively small and I don't need to setup notifications in NSNotificationCenter, but I may be wrong. I would really like to hear this is not the only solution.
Thanks in advance. I hope I was clear enough, but if you want/need any additional details on my particular situation, let me know and I will gladly elaborate.
if I understood the question correctly, your ViewController should be laying out the keys within it's view. A good, but not the only, place to do this is in viewDidLayoutSubviews which a method you can override on UIViewController.
Now if your views should maintain their internal layout. i.e if you buttons/keys have any subviews, you should update those in layoutSubviews on UIView as you mentioned.
Both methods will be called in response to changes in the bounds or center of your parent view.
As far as rotation changes are concerned, in iOS 8, you should use viewWillTransitionToSize:withTransitionCoordinator: or willTransitionToTraitCollection:withTransitionCoordinator:
depending on your needs.
I highly recommend that you write your layout independent of orientation. You should just use the containing view's bounds for reference and never hard code in any frames. For example perhaps one of your keys should be 1/56 the width of it's superview instead of a magical number for portrait and landscape.

+[UIView transitionFromView:toView:...] with multiple views

So here's the situation:
I have let's say 20 views who are all subviews of the same view. Now I want to remove and add new views in an animated matter.
I previously did this by using regular UIView animations and fading them out or in respectively. The problem is though that the animation isn't flawless when the new subview who is to be inserted overlaps with the subviews who are fading out. So I tried using the +[UIView transitionFromView:toView:...] animation block to make the animation cross dissolve. This works well, animation looks good.
This basically solves my issue. The only problem is that it might be that I want to replace 2 subviews with one bigger subview. This doesn't really work out as I can't just pas nil to the transition method.
So my question basically is how I can simultaneously cross dissolve multiple subviews no matter how many views are animated?
Thanks for your help!
Have you tried putting the views to remove inside a transparent bigger view? So you just call transitionFromViewToView using the container with the 2 little ones inside and the big one that is entering?
You can use + [UIView transitionWithView:duration:options:animations:completion:], passing the common superview (usually self.view of your view controller) to perform all animations at once.
Excerpt from the doc:
This method applies a transition to the specified view so that you can
make state changes to it. The block you specify in the animations
parameter contains whatever state changes you want to make. You can
use this block to add, remove, show, or hide subviews of the specified
view. If you want to incorporate other animatable changes, you must
include the UIViewAnimationOptionAllowAnimatedContent key in the
options parameter.

Is there any way to allow a view to be automatically "click-throughable" in a Storyboard?

I have a dark overlay I occasionally present over the full tableview, and I'd like to set it up in the Storyboard, but when I do, it obfuscates access to all the views beneath it (AKA all the views).
Setting it to hidden makes it transparent, but you can still click it. Is there any way to make it click-throughable all the time?
Set the property userInteractionEnabled to NO on your dark overlay view and all user touches should pass through.
Edit:
The simple answer is no. You cannot change how interface builder works. Besides, it's better to do things in code, especially when collaborating.

ios uibutton hidden: does this automatically make the button disabled?

I just have a knowledge question about UIButtons / iOS in general.
Let's say you have a UIButton. You set the 'hidden' property to YES. This makes it no longer visible in view, right? But I noticed that while it's no longer visible, it is also no longer clickable either. So, does this mean that setting hidden = YES also sets enabled = NO?
Just curious. Thanks y'all.
UIButton and all controls inherits common properties from UIView like hidden, backgroundColor, etc.
Class reference of UIView says if any view is hidden then it will not receive input events
Class reference of UIView says:
A hidden view disappears from its window and does not receive input
events. It remains in its superview’s list of subviews, however, and
participates in autoresizing as usual. Hiding a view with subviews has
the effect of hiding those subviews and any view descendants they
might have. This effect is implicit and does not alter the hidden
state of the receiver’s descendants.
you can find this over Here.
It does. Setting the buttons hidden property to YES will disable any user interaction. This is true for other UI elements as well as just UIButton.
Yes you can't touch button when it is hidden.If you wanna touch it then you must make it btn.hidden = NO;. Hidden means disable the user interaction.
Not sure. Best way to find out would be an NSLog returning button.hidden

Resources