Programing

Swift에 포함 된 경우

lottogame 2020. 7. 8. 08:13
반응형

Swift에 포함 된 경우


내 앱을 Swift 언어로 변환하려고합니다.

이 코드 줄이 있습니다.

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

그것을 스위프트로 변환하는 방법?

에서 애플의 워드 프로세서 , 그런 방법이 없습니다.


iOS 9 용 업데이트 :

iOS 9 이상 (Xcode 7 b1 기준)을 대상으로하는 UIAppearance경우 varargs를 사용하지 않는 새로운 방법이 프로토콜에 있습니다.

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

다음과 같이 사용할 수 있습니다.

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

여전히 iOS 8 또는 이전 버전을 지원해야하는 경우이 질문에 대한 다음 원래 답변을 사용하십시오.

iOS 8 및 7의 경우 :

Obj-C varargs 메소드는 Swift와 호환되지 않으므로이 메소드는 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

ios 10 swift 3

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

iOS 8 및 7의 경우 :

Alex의 답변을 기반으로 범주를 사용하여 여러 컨테이너를 지정합니다. 이것은 Apple appearanceWhenContainedIn이 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

그런 다음 #import "UIAppearance+Swift.h"브리징 헤더에 추가 하십시오.

스위프트에서 사용하려면 :

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

CVarArgType을 사용하여 방법을 찾을 수 있다면 좋았지 만 깨끗한 해결책을 찾지 못했습니다.


@tdun에서 영감을 얻은 덜 추악하지만 여전히 추악한 해결 방법이 있습니다.

  1. Objective-C 모양을 담을 클래스를 만듭니다. 이 예제의 목적으로 호출 해 봅시다 AppearanceBridger.
  2. 이 클래스를 브리징 헤더에 추가하십시오. 브리징 헤더가 없으면을 만드십시오 .
  3. Create a class method in AppearanceBridger named +(void)setAppearance and put the Objective-C appearance code in this method. For example:


+ (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!

Hope this works well for people who see it.


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

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

I named mine WorkaroundViewController...

Now in (WorkaroundViewController.m):

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

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

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

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

var work : WorkaroundViewController = WorkaroundViewController()

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


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

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

I have created a repo for you guys who wanna use 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


Swift 4: iOS 9+

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

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.


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.


You should be able to just translate the Objective-C syntax into Swift syntax.

In swift the methods should be declared like this:

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

So you can try this:

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

I still have to figure out if this is the clean way to call a class method in Swift though.

Hope this helps,

참고URL : https://stackoverflow.com/questions/24136874/appearancewhencontainedin-in-swift

반응형