当被包含在雨燕中时

我想把我的应用程序转换成斯威夫特语言。

我有一行代码:

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

如何转换成斯威夫特?

Apple's docs中,没有这样的方法。

41275 次浏览

您应该能够将 Objective-C语法翻译成 Swift语法。

应迅速宣布这些方法:

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

So you can try this:

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

但是,我仍然必须弄清楚这是否是在 Swift中调用类方法的干净方法。

希望这对你有帮助,

你可以用这个:

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

在 Swift 中删除 ContainedIn 时显示。这个答案是为了 Beta 5改变所有条形按钮文本的外观。

It seems Swift (at least as of Beta5) isn't able to support it for reasons unknown to me. Perhaps the language feature required is still in progress, as I can only assume they left it out of the interface for a good reason. Like you said, according to the docs it's still available in ObjC. Really disappointing.

这是我用过的一个丑陋的解决方案... ..。

Just make an Objective-C Cocoa Touch Class (UIViewController), named whatever you want.

我把我的命名为 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 项目使用 创建桥接头,然后在 Swift 代码中初始化 Objective-C ViewController,如下所示(同样,只是我的示例) :

var work : WorkaroundViewController = WorkaroundViewController()

然后你就完了! 让我知道它是否适合你... 就像我说的,它的丑陋,但工程!

这里有一个不那么丑陋,但仍然丑陋的变通方法,灵感来自@tdun。

  1. 创建一个类来保存 Objective-C 的外观。
  2. 将此类添加到桥接头。如果没有桥接头,则为 创造一个
  3. AppearanceBridger中创建一个名为 +(void)setAppearance的类方法,并在该方法中放入 Objective-C 外观代码:


+ (无效) set卖相{
[[包含时 UIView 外观: [ UITableViewHeaderFooterView 类] ,空] setBackground Color: [ UIColor whiteColor ]] ;
}

  1. 在你设置外观的 Swift 代码中,调用 AppearanceBridger.setAppearance()就可以了!

希望这对看到它的人有用。

Update for iOS 9:

如果你的目标是 iOS 9 + (从 Xcode 7 b1开始) ,在 UIAppearance协议中有一个新的方法,它不使用 varargs:

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

可以这样使用:

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

如果您仍然需要支持 iOS8或更早的版本,请使用以下原始答案来回答这个问题。

For iOS 8 & 7:

这些方法对 Swift 不可用,因为 Obj-C varargs 方法与 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

只要确保在桥接头中使用 #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

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

外观 + 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

如果我能找到一种使用 CVarArgType的方法是好的,但是我没有找到干净的解决方案。

我为你们这些想用 CocoaPods的人创建了一个回购协议:

  1. 把这个加入你的 Podfile:

    pod 'UIViewAppearanceSwift'
    
  2. Import in your class:

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

这可以扩展到符合 UI卖相协议的任何类——而不仅仅是 UIViews。所以这里有一个更通用的版本:

外观 + Swift.h

#import <UIKit/UIKit.h>


@interface NSObject (UIAppearance_Swift)


+ (instancetype)appearanceWhenContainedWithin:(Class<UIAppearanceContainer>)containerClass;


@end

外观 + 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

ios 10 swift 3

UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Kapat"

Swift 4: iOS 9 + 雨燕4: iOS 9 +

UIProgressView.appearance(whenContainedInInstancesOf: [LNPopupBar.self]).tintColor = .red