Swift에 포함 된 경우


125

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

이 코드 줄이 있습니다.

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

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

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


1
@LukeTheObscure 아래의 대답을 확인하십시오 ... 못생긴,하지만 작동합니다.
tcd September

답변:


230

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

15
UIBarButtonItem은 UIView가 아니며 별도로 확장해야합니다.
Sergey Skoblikov

7
적어도 iOS8에서 UIAppearance + Swift.h는 UIKit / UIKit.h를 가져와야합니다
Chase

UIView 대신 UIBarButtonItem을 대상으로하는 다른 메소드를 만드는 경우에도 UIBarButtonItem을 지원할 수 있습니다. @interface UIBarButtonItem (UIViewAppearance_Swift)
Michael Peterson

1
@rptwsthi : 나는 스위프트 3 예제를 추가 한, 아주 약간 다르다
알렉스 Pretzlav

1
Swift 3.2의 iOS 9 버전은 UIBarButtonItem.appearance (whenContainedInInstancesOf : [UISearchBar.self]). title = "완료"
Eli Burke

31

ios 10 swift 3

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

1
이 downvote 이유는 'iOS10 스위프트 3 ... 감사에서 그것을 할 방법이야 이후 몰라
Vassily

14

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을 사용하여 방법을 찾을 수 있다면 좋았지 만 깨끗한 해결책을 찾지 못했습니다.


varargs의 고장에 대한 좋은 해결 방법! Apple의 iOS 9 전용 방법을 사용하는 것 이외의 일반적인 해결책은 없습니다.
Alex Pretzlav 2016 년

12

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

  1. Objective-C 모양을 담을 클래스를 만듭니다. 이 예제의 목적으로 호출 해 봅시다 AppearanceBridger.
  2. 이 클래스를 브리징 헤더에 추가하십시오. 브리징 헤더가 없으면을 만드십시오 .
  3. AppearanceBridger명명 된 클래스 메서드를 만들고이 메서드에 +(void)setAppearanceObjective-C 모양 코드를 넣습니다. 예를 들면 다음과 같습니다.


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

  1. 모양을 설정하는 Swift 코드에서 전화 AppearanceBridger.setAppearance()하면 잘 갈 수 있습니다!

이것이 그것을 보는 사람들에게 잘 작용하기를 바랍니다.


4

내가 사용한 못생긴 해결 방법은 다음과 같습니다 ....

원하는 이름으로 Objective-C Cocoa Touch Class (UIViewController)를 만드십시오.

나는 내 이름을 WorkaroundViewController...

이제 ( WorkaroundViewController.m)에서 :

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

다음에 대한 Objective-C 모양 코드를 실행하십시오 .appearanceWhenContainedIn()(내 예제는 다음과 같습니다).

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

그런 다음 Swift 프로젝트 의 브리징 헤더 를 만든 다음 Swift 코드에서 Objective-C ViewController를 초기화하십시오 (다시 예제).

var work : WorkaroundViewController = WorkaroundViewController()

그럼 끝났어요! 그것이 당신을 위해 작동하는지 알려주세요 ... 내가 말했듯이, 그것은 추악하지만 작동합니다!


그것은 tmp 솔루션입니다, 나는 우리가 더 나은 길을 찾거나 기다려야한다고 생각합니다 :)
AlexZd

@AlexZd, 절대적으로, 그것들이 신속하게 포함되기를 바랍니다 ...하지만 지금은 필요하다면 나중에갑니다!
tcd September

4

UIViews뿐만 아니라 UIAppearance 프로토콜을 준수하는 모든 클래스로 확장 할 수 있습니다. 보다 일반적인 버전은 다음과 같습니다.

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

3

나는 당신을 사용하고자하는 사람들을 위해 레포를 만들었습니다 CocoaPods.

  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



0

Swift (적어도 Beta5에서)는 나에게 알려지지 않은 이유로 그것을 지원하지 못하는 것 같습니다. 아마도 필요한 언어 기능이 아직 진행 중일 것입니다. 왜냐하면 나는 정당한 이유 때문에 인터페이스에서 빠져 나온 것으로 가정 할 수 있기 때문입니다. 당신이 말했듯이, 문서에 따르면 여전히 ObjC에서 사용할 수 있습니다. 정말 실망합니다.


이것은 @spinillos 방법을 사용하여 베타 5에서 나에게 효과적이었습니다.
Jason Crump

그렇습니다.하지만 appearanceWhenContainedIn:여전히 테이블에서 벗어났습니다.
hlfcoding

-3

이것을 사용할 수 있습니다 :

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

편집 : Swift에서 appearanceWhenContainedIn이 제거되었습니다. 이 답변은 베타 5가 모든 막대 버튼의 텍스트 모양을 변경하기위한 것입니다.


1
또한 Swift는 유추하여 유형을 알고 있으므로 UIControlState.Normal사용할 필요가 없습니다 .Normal.
벤 Lachman

12
이없는 특정 하나, 모든 UIBarButtonItems에 대한 모양을 변경합니다
Kostiantyn 코발에게

@KonstantinKoval 정확하게-그것이 외관 프록시의 목적입니다. 모든 뷰 컨트롤러에 상용구 코드 / 방법 호출을 포함하지 않고도 전체 애플리케이션을 스타일링 할 수 있습니다.
Craig Otis

3
이것은 실제로 질문에 대답하지 않지만 Swift appearanceWhenContainedIn는 제거되었습니다.
Tim Windsor Brown

-7

Objective-C구문을 다음으로 변환 할 수 있어야합니다.Swift 구문 .

신속하게 메소드를 다음과 같이 선언해야합니다.

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

그래서 당신은 이것을 시도 할 수 있습니다 :

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

이것이 클래스 메소드를 호출하는 깨끗한 방법인지 여전히 알아야합니다. Swift .

도움이 되었기를 바랍니다,


1
신속 하게이 ConContainIn이있을 때이 메소드는 없습니다 컴파일되지 않습니다. 오류 : 'UIBarButtonItem.Type'에 'appearanceWhenContainedIn'이라는 멤버가 없습니다.
AlexZd

안녕하세요 @AlexZd, 귀하의 의견은 실제 XCode 6 베타를 기반으로하지만 UIAppearance프로토콜 설명서 ( 적합한 내용)를 보면 UIBarButtonItem`appearanceWhenContainedIn (_ :) 메소드가 존재합니다 (아직 Swift에서는 아직 구현되지 않았습니다) : developer.apple .com / library / prerelease / ios / documentation / UIKit /…
Zedenem

@Zedenem 나는 정말 바보 야, 알고 당신은 우리를 믿고 싶어하지 않는다 -하지만 말 그대로 스위프트에서 호출 할 수 없습니다이 방법은 설명서를 참조하십시오 : developer.apple.com/library/ios/documentation/UIKit/Reference/...를 - 이 방법은 Swift에서 숨겨져 있습니다
powerj1984

안녕하세요 @ powerj1984, 당신을 믿기를 원하지 않습니다. 나는 이것이 스위프트의 베타 상태에 의한 것이라고 대답을 썼을 때 단지 바라고 있었다. 이 방법은 더 이상 사용되지 않지만 Swift에서 숨겨져 있다는 사실은 정말 이상하며 Apple의 설명이 없어도 최악입니다 ...하지만 왜 그런지 이해하지 못하더라도 내 대답은 옳습니다. 잘못되었습니다. 어쩌면 스위프트에 우리가 그렇게 할 수있을 것이라고 생각하지 않는 기능이
있습니까

하하, 미안해-난 정말 믿기 싫어 애플이 망치는 것은 바보 같은 일이다. 도대체 이상하다!
powerj1984
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.