在Swift中包含的外观

我试图将我的应用程序转换为Swift语言。

我有这样的代码行:

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:textDictionary forState:UIControlStateNormal]; 

如何将其转换为Swift?

在苹果的文档中 ,没有这样的方法。

iOS 9更新:

如果您的目标是iOS 9+(从Xcode 7 b1开始),则UIAppearance协议中有一个不使用可变参数的新方法:

 static func appearanceWhenContainedInInstancesOfClasses(containerTypes: [AnyObject.Type]) -> Self 

可以这样使用:

 UITextField.appearanceWhenContainedInInstancesOfClasses([MyViewController.self]).keyboardAppearance = .Light 

如果您仍然需要支持iOS 8或更早版本,请对此问题使用以下原始答案。

对于iOS 8和7:

这些方法不适用于Swift,因为Obj-C可变参数方法与Swift不兼容(请参阅http://www.openradar.me/17302764 )。

我写了一个无变化的解决方法,在Swift中工作(我重复UIBarItem的同样的方法,它不从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; @end NS_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 

只要确保在桥接头文件中input#import "UIAppearance+Swift.h"

然后,从Swift调用(例如):

 # 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" 

对于iOS 8和7:

我使用基于Alex的答案来指定多个容器的类别。 这是一个解决方法,直到苹果正式支持Swift中的appearanceWhenContainedIn

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 

然后添加#import "UIAppearance+Swift.h"到您的桥接头。

从Swift使用

 TextField.appearanceWhenContainedWithin([MyViewController.self, TableViewController.self]).keyboardAppearance = .Light 

如果我能find一种使用CVarArgType的方法,这是很好的,但是我没有find干净的解决scheme。

这是一个不那么丑陋,但仍然丑陋,由@tdun启发的解决方法。

  1. 创build一个类来保存你的Objective-C外观。 为了这个例子的目的,我们称之为AppearanceBridger
  2. 将这个类添加到您的桥接头。 如果您没有桥接头,请创build一个 。
  3. 在名为+(void)setAppearance AppearanceBridger创build一个类方法,并将Objective-C外观代码放在此方法中。 例如:

 + (void)setAppearance { [[UIView appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setBackgroundColor:[UIColor whiteColor]]; } 
  1. 在您设置外观的Swift代码中,调用AppearanceBridger.setAppearance() ,您应该很好!

希望这对那些看到它的人很好。

这是一个丑陋的解决方法,我用….

只要制作一个Objective-Ccocoa触摸类(UIViewController),命名任何你想要的。

我命名我的WorkaroundViewController

现在在( WorkaroundViewController.m )中:

 -(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 

运行.appearanceWhenContainedIn() (这里是我的例子)的Objective-C外观代码:

 [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Avenir-Light" size:16.0f]}]; 

然后为你的Swift项目创build一个桥接头 ,然后在你的Swift代码中初始化你的Objective-C ViewController,就像这样(再次,就是我的例子):

 var work : WorkaroundViewController = WorkaroundViewController() 

那你就完成了! 让我知道,如果它适合你…就像我说的,这是丑陋的,但工作!

这可以扩展到任何符合UIAppearance协议的类 – 不仅仅是UIViews。 所以这是一个更通用的版本:

UIAppearance + Swift.h

 #import <UIKit/UIKit.h> @interface NSObject (UIAppearance_Swift) + (instancetype)appearanceWhenContainedWithin:(Class<UIAppearanceContainer>)containerClass; @end 

UIAppearance + Swift.m

 #import "UIAppearance+Swift.h" @implementation NSObject (UIAppearance_Swift) + (instancetype)appearanceWhenContainedWithin:(Class<UIAppearanceContainer>)containerClass { if ([self conformsToProtocol:@protocol(UIAppearance)]) { return [(id<UIAppearance>)self appearanceWhenContainedIn:containerClass, nil]; } return nil; } @end 

我为你们想要使用CocoaPods人创build了一个回购:

  1. 将其添加到您的Podfile

     pod 'UIViewAppearanceSwift' 
  2. 导入你的课堂:

     import UIViewAppearanceSwift func layout() { UINavigationBar.appearanceWhenContainedWithin(MFMailComposeViewController.self).barStyle = .Black UIBarButtonItem.appearanceWhenContainedWithin(UISearchBar.self).setTitleTextAttributes([NSFontAttributeName: UIFont.systemFontOfSize(15)], forState: UIControlState.Normal) } 
  3. 参考: https : //github.com/levantAJ/UIViewAppearanceSwift

看来Swift(至less从Beta5开始)不能以我未知的原因来支持它。 也许所需的语言function仍在进行中,因为我只能假设他们将其从界面中排除出去是有原因的。 就像你说的那样,根据文档,它仍然可以在ObjC中find。 真令人失望。

你可以使用这个:

 UIBarButtonItem.appearance().setTitleTextAttributes(textDictionary, forState: UIControlState.Normal) 

编辑:appearanceWhenContainedIn在Swift中被删除。 这个答案是为了改变所有酒吧button的文字的外观。

您应该能够将Objective-C语法转换为Swift语法。

在迅速的方法应该这样宣布:

 func appearanceWhenContainedIn(containerClass : <UIAppearanceContainer>) func setTitleTextAttributes(_ attributes: NSDictionary!, forState state: UIControlState) 

所以你可以试试这个:

 UIBarButtonItem.appearanceWhenContainedIn(UINavigationBar).setTitleTextAttributes(textDictionary, forState: UIControlStateNormal) 

我仍然需要弄清楚这是否是在Swift调用类方法的干净方式。

希望这可以帮助,