ios Swift 中的出现时包含在

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24136874/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 00:45:41  来源:igfitidea点击:

appearanceWhenContainedIn in Swift

iosswiftuiappearance

提问by AlexZd

I'm trying to convert my app to the Swift language.

我正在尝试将我的应用程序转换为 Swift 语言。

I have this line of code:

我有这行代码:

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

How to convert it to Swift?

如何将其转换为 Swift?

In Apple's docs, there is no such method.

Apple 的文档中,没有这样的方法。

回答by Alex Pretzlav

Update for iOS 9:

iOS 9 更新:

If you're targeting iOS 9+ (as of Xcode 7 b1), there is a new method in the UIAppearanceprotocol which does not use varargs:

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

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.

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

For iOS 8 & 7:

对于 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).

这些方法对 Swift 不可用,因为 Obj-C 可变参数方法与 Swift 不兼容(参见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):

我编写了一个适用于 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

Just be sure to #import "UIAppearance+Swift.h"in your bridging header.

只要确保#import "UIAppearance+Swift.h"在您的桥接头中。

Then, to call from Swift (for example):

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

# Swift 2.x:
UITextField.my_appearanceWhenContainedIn(MyViewController.self).keyboardAppearance = .Light

# Swift 3.x:
UITextField.my_appearanceWhenContained(in: MyViewController.self).keyboardAppearance = .light

回答by AlexZd

ios 10 swift 3

ios 10 swift 3

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

回答by Yoichi Tagaya

For iOS 8 & 7:

对于 iOS 8 和 7:

I use a category based on Alex's answer to specify multiple containers. This is a workaround until Apple officially supports appearanceWhenContainedInin Swift.

我使用基于 Alex 回答的类别来指定多个容器。在 Apple 正式支持appearanceWhenContainedInSwift之前,这是一种解决方法。

UIAppearance+Swift.h

UIAppearance+Swift.h

@interface UIView (UIAppearance_Swift)
/// @param containers An array of Class<UIAppearanceContainer>
+ (instancetype)appearanceWhenContainedWithin: (NSArray *)containers;
@end

UIAppearance+Swift.m

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.

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

To use from Swift:

从 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.

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

回答by Baub

Here's a less ugly, but still ugly, workaround inspired by @tdun.

这是一个不那么丑陋但仍然丑陋的解决方法,其灵感来自@tdun。

  1. Create a class to hold your Objective-C appearance. For the purposes of this example, let's call it AppearanceBridger.
  2. Add this class to your bridging header. If you don't have a bridging header, create one.
  3. Create a class method in AppearanceBridgernamed +(void)setAppearanceand put the Objective-C appearance code in this method. For example:
  1. 创建一个类来保存您的 Objective-C 外观。出于本示例的目的,我们将其称为AppearanceBridger
  2. 将此类添加到您的桥接头中。如果您没有桥接头,请创建一个.
  3. AppearanceBridgernamed中创建一个类方法,并将+(void)setAppearanceObjective-C的外观代码放在这个方法中。例如:


+ (void)setAppearance {
    [[UIView appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setBackgroundColor:[UIColor whiteColor]];
}

  1. In your Swift code where you set the appearance, call AppearanceBridger.setAppearance()and you should be good to go!
  1. 在您设置外观的 Swift 代码中,调用AppearanceBridger.setAppearance()即可!

Hope this works well for people who see it.

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

回答by tcd

Here's an ugly workaround solution I used....

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

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

只需创建一个 Objective-C Cocoa Touch 类(UIViewController),任意命名即可。

I named mine WorkaroundViewController...

我给我取名WorkaroundViewController...

Now in (WorkaroundViewController.m):

现在在 ( WorkaroundViewController.m) 中:

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

Run the Objective-C appearance code for .appearanceWhenContainedIn()(here's my example):

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

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

Then create a bridging headerfor your Swift project and then initialize your Objective-C ViewController in your Swift code, like this (again, just my example):

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

var work : WorkaroundViewController = WorkaroundViewController()

Then you're done! Let me know if it works for you... Like I said, it's ugly, but works!

然后你就完成了!让我知道它是否适合你......就像我说的,它很丑,但有效!

回答by Eddie K

This can be extended to any class that conforms to the UIAppearance protocol -- not just UIViews. So here's a more generic version:

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

UIAppearance+Swift.h

UIAppearance+Swift.h

#import <UIKit/UIKit.h>

@interface NSObject (UIAppearance_Swift)

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

@end

UIAppearance+Swift.m

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

回答by Tai Le

I have created a repo for you guys who wanna use CocoaPods:

我为想要使用的你们创建了一个仓库CocoaPods

  1. Add this into your 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

  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

回答by Maksim Kniazev

Swift 4: iOS 9+

斯威夫特 4:iOS 9+

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

回答by hlfcoding

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.

由于我不知道的原因,Swift(至少从 Beta5 开始)似乎无法支持它。也许所需的语言功能仍在开发中,因为我只能假设他们有充分的理由将其排除在界面之外。就像你说的,根据文档,它在 ObjC 中仍然可用。真令人失望。

回答by spinillos

You can use this:

你可以使用这个:

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

Edit: appearanceWhenContainedIn was removed in Swift. This answer was for the Beta 5 to change the appearance of the text of all bar buttons.

编辑:appearanceWhenContainedIn 在 Swift 中被删除。这个答案是让 Beta 5 改变所有条形按钮文本的外观。