When do UIAppearance proxy rules get applied to new view controller? - ios

I'm wandering when exactly do UIAppearance rules get applied to some new view controller?
I've made some global rules and I call them in my app delegate. That way all UIButtons look that same. But now I want to modify just appearance of one UIButton. I've tried putting the code to remove it's background inside - (void)viewDidLoad but it's not working - UIAppearance rules aren't applied yet. In one ViewController I put modification code inside - (void)viewWillLayoutSubviews and it worked perfectly, but now in another ViewController it doesn't work (code is the same).
Where is it safe to override UIAppearance rules?

According to the 2011 WWDC video introducing UIAppearance, the customizations are applied right before -layoutSubviews is called on the view.

If you're looking to customise one specific button you should either:
Alter the properties of the button instance directly, and not touch the appearance settings for the class, or
Use the appearanceWhenContainedIn: method like below:
[[UIButton appearanceWhenContainedIn:[CustomView class], nil]
setBackgroundImage:myButtonImage
forState:UIControlStateNormal];
That way you can still use the appearance proxy for your specific button (when you know it's contained in a specific view), and not alter the general appearance settings.

Related

iOS add view to Button in IB

I am trying to add a view on a UIButton inside IB. The only problem it doesn't allow me to put in inside the button only on top?
Is this not possible through IB or am I doing it wrong?
It's not possible in Interface Builder. You have to add it in code.
You should not do this:
Do Not Customize Controls by Embedding Subviews
Although it is technically possible to add subviews to the standard system controls—objects that inherit from UIControl—you should never customize them in this way. Controls that support customizations do so through explicit and well-documented interfaces in the control class itself. For example, the UIButton class contains methods for setting the title and background images for the button. Using the defined customization points means that your code will always work correctly. Circumventing these methods, by embedding a custom image view or label inside the button, might cause your application to behave incorrectly now or at some point in the future if the button’s implementation changes.
https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/WindowsandViews/WindowsandViews.html#//apple_ref/doc/uid/TP40009503-CH2-SW26
If you need to add a UIView on your UIButton you can achieve it in 2 different ways
The easy way is to follow Cyrille answer: you can do it programmatically because IB doesn't allow you to modify a UIBUtton adding a view on it
The hard way is to create your custom button (let me call it "MYCustomButton"), that extends a UIButton, and use it in your application. With this way when you need to modify the buttons in your interface, you can achieve it modifying the XIB of the "MYCustomButton".

What is the correct approach for a custom UIToolBar?

Is it better - better in the sense of not getting rejected from the Apple store - when trying to create a custom* UIToolbar to either:
Option A
Add the oversize middle button as a UIButton to the self.navigationController.view this is key as I'm adding a UIButton to the navigationController which seems to contradict the apple docs
Use UIToolbar appearance to implement the custom background
Option B
Create a UIToolbar and add it as a subview of the current ViewController in UINavigationController
Add the UIButton as a subview of the current ViewController in UINavigationController
Use UIToolBar's method setBackgroundImage to add the custom background
*Custom background, Oversized middle button
This is the shape of the toolbar:
Extra details: This app is for iOS 5.X or greater. It uses UINavigationController. Key challenge is that a section of the app hide/shows the navigationbar depending on the state of the app.
Option A means I don't have to workout where to place the UIToolBar, it's a challenge to work out where to place the UIToolbar because a) if I'm showing or hiding the navigationBar this shifts everything up/down vertically b) iPhone 5 with extra vertical space - I can't use autolayout as I'm support iOS 5 and I haven't really worked out how to use autoresizing masks. I'mu using hard coded "magic" numbers.
I wouldn't do either of those.
UIToolbar is nice when you want to do what it does, and it does allow some basic customization. But in this case you want a toolbar-like view that draws itself in a way that UIToolbar doesn't seem to allow for. You probably know exactly what items you want to appear in your "toolbar", and it's unlikely that you'll need to handle arbitrary assortments of UIBarItems.
So, instead of giving yourself a headache trying to force UIToolbar to do something that it was never designed for, just create a simple view containing your background image (part of which will be transparent). Place some image-based UIButtons in the view, and call it a day. It wouldn't be a bad idea to create a custom UIView subclass representing your toolbar so that all the setup is nicely packaged up in one place, and so that you can reuse the toolbar in multiple views if you need to.

I want to apply a setting globally (to all text UIViews in my app)

I have a bunch of text views, and I now want to turn autoresizing on in all of them. I don't want to highlight each one individually, and I only want the changes to apply to all text views in the app. So I don't want to modify the framework. I will be sure to pick the best answer.
EDIT: I guess I should have mentioned earlier that I am using storyboards.
In iOS 5.0+, you should be able to use the appearance proxy for UITextView like so:
[[UITextView appearance] setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
This would make all UITextView's respond with a flexible width and height. Here's a great tutorial on how to use the proxy for other UI controls:
http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5
EDITED:
This code should work and I've tested this in both the simulator and on an iPhone directly, even though the autoresizingMask property in UIView.h is not flagged with UI_APPEARANCE_SELECTOR. This post seems to indicate that its possible for a property to not have this flag, yet still obey messages from the appearance proxy. All that said, #rmaddy is right. It might be a risk to rely on this long-term.
One option is to subclass UITextView and create a CustomTextView. In its init methods or layoutSubviews method, set the autoresizing mask and then use that CustomTextView in your project. One advantage with usage of init method for setting this is that, you can later override this autoresize mask.

Alternative to setTintColor for pre-iOS5 UIBarButtonItems?

are there any alternatives to using the accessor setTintColor for UIBarButtonItems in order to add ios4 compatibility?
is it possible to modify the setter to include a conditional statement for systemVersion (without subclassing UIBarButtonItem)?
There are three approaches to do this. First, is to draw a button with CoreGraphic. Second, use a custom image. The third approach is probably the easiest and allows you to use a tintColor property for dynamic changes if wanted.
The idea is to create a UISegmentedControl and stylize it to look like a button and use that tintColor property to change the color of the "button".
You can find specific details at this webpage http://charles.lescampeurs.org/2011/02/10/tint-color-uibutton-and-uibarbuttonitem .

Replacing container view of UIActionSheet with my custom view

I am developing an iPhone application in which I want to customize the action sheet with my own background image for action sheet and buttons.
I can write my own view which behaves like UIActionSheet. But, UIActionSheet by itself has some standard behavior like blocking orientation events. We might not be aware of such things. So, for safety purpose, it is better to have UIActionSheet itself; by replacing all its views with my custom view.
For this I have done the following things:
1. Create UIActionSheet. Call showOnView: on that action sheet.
2. Set the delegate as myController
3. In the delegate method willPresentActionSheet: remove all the subviews and add my custom view as action-sheet's sub-view
The problem is that I cannot get the animation affect of Action Sheet with my custom view, Because,UIActionSheet is animated before calling willPresentActionSheet (in showInView). If I override showInView and add my own animation I might miss the behavior like:
1. Blocking orientation events
2. Some of the views (the argument of showInView:) might no support orientation. I should be able to apply same orientation to my action-sheet in showInView.
Could someone help me out in achieving customization?
Thanks and Regards, Deepa

Resources