appearanceWhenContainedIn in Swift
Update for iOS 9:
If you're targeting iOS 9+ (as of Xcode 7 b1), there is a new method in the UIAppearance
protocol which does not use varargs:
static func appearanceWhenContainedInInstancesOfClasses(containerTypes: [AnyObject.Type]) -> Self
Which can be used like so:
UITextField.appearanceWhenContainedInInstancesOfClasses([MyViewController.self]).keyboardAppearance = .Light
If you still need to support iOS 8 or earlier, use the following original answer to this question.
For iOS 8 & 7:
These methods are not available to Swift because Obj-C varargs methods are not compatible with Swift (see http://www.openradar.me/17302764).
I wrote a non-variadic workaround which works in Swift (I repeated the same method for UIBarItem
, which doesn't descend from UIView
):
// UIAppearance+Swift.h#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface UIView (UIViewAppearance_Swift)// appearanceWhenContainedIn: is not available in Swift. This fixes that.+ (instancetype)my_appearanceWhenContainedIn:(Class<UIAppearanceContainer>)containerClass;@endNS_ASSUME_NONNULL_END
—
// UIAppearance+Swift.m#import "UIAppearance+Swift.h"@implementation UIView (UIViewAppearance_Swift)+ (instancetype)my_appearanceWhenContainedIn:(Class<UIAppearanceContainer>)containerClass { return [self appearanceWhenContainedIn:containerClass, nil];}@end
Just be sure to #import "UIAppearance+Swift.h"
in your bridging header.
Then, to call from Swift (for example):
# Swift 2.x:UITextField.my_appearanceWhenContainedIn(MyViewController.self).keyboardAppearance = .Light# Swift 3.x:UITextField.my_appearanceWhenContained(in: MyViewController.self).keyboardAppearance = .light
ios 10 swift 3
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Kapat"
For iOS 8 & 7:
I use a category based on Alex's answer to specify multiple containers. This is a workaround until Apple officially supports appearanceWhenContainedIn
in Swift.
UIAppearance+Swift.h
@interface UIView (UIAppearance_Swift)/// @param containers An array of Class<UIAppearanceContainer>+ (instancetype)appearanceWhenContainedWithin: (NSArray *)containers;@end
UIAppearance+Swift.m
@implementation UIView (UIAppearance_Swift)+ (instancetype)appearanceWhenContainedWithin: (NSArray *)containers{ NSUInteger count = containers.count; NSAssert(count <= 10, @"The count of containers greater than 10 is not supported."); return [self appearanceWhenContainedIn: count > 0 ? containers[0] : nil, count > 1 ? containers[1] : nil, count > 2 ? containers[2] : nil, count > 3 ? containers[3] : nil, count > 4 ? containers[4] : nil, count > 5 ? containers[5] : nil, count > 6 ? containers[6] : nil, count > 7 ? containers[7] : nil, count > 8 ? containers[8] : nil, count > 9 ? containers[9] : nil, nil];}@end
Then add #import "UIAppearance+Swift.h"
to your bridging header.
To use from Swift:
TextField.appearanceWhenContainedWithin([MyViewController.self, TableViewController.self]).keyboardAppearance = .Light
It was good if I could find a way using CVarArgType, but I found no clean solution.