appearanceWhenContainedIn in Swift appearanceWhenContainedIn in Swift ios ios

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.