ios swift uiappearance

ios - appearanceWhenContainedIn en Swift



uiappearance (11)

Para iOS 8 y 7:

Utilizo una categoría basada en la respuesta de Alex para especificar contenedores múltiples. Esta es una solución temporal hasta que Apple admite oficialmente la appearanceWhenContainedIn en 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

A continuación, agregue #import "UIAppearance+Swift.h" a su encabezado de puente.

Para usar de Swift :

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

Era bueno si podía encontrar una forma de usar CVarArgType , pero no encontré una solución limpia.

Estoy tratando de convertir mi aplicación al lenguaje Swift.

Tengo esta línea de código:

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

¿Cómo convertirlo a Swift?

En los documentos de Apple , no hay tal método.


Actualización para iOS 9:

Si su objetivo es iOS 9+ (a partir de Xcode 7 b1), hay un nuevo método en el protocolo UIAppearance que no utiliza varargs:

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

Que se puede usar así:

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

Si aún necesita compatibilidad con iOS 8 o anterior, use la siguiente respuesta original a esta pregunta.

Para iOS 8 y 7:

Estos métodos no están disponibles para Swift porque los métodos de vajang Obj-C no son compatibles con Swift (consulte http://www.openradar.me/17302764 ).

Escribí una solución no variada que funciona en Swift (repetí el mismo método para UIBarItem , que no desciende de 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

Solo asegúrese de #import "UIAppearance+Swift.h" en su encabezado de puente.

Luego, para llamar desde Swift (por ejemplo):

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


Aquí hay una solución desagradable que utilicé ...

Simplemente haga una clase Objective-C Cocoa Touch (UIViewController), con el nombre que desee.

Llamé a mi mina WorkaroundViewController ...

Ahora en ( WorkaroundViewController.m ):

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

Ejecute el código de apariencia de Objective-C para .appearanceWhenContainedIn() (aquí está mi ejemplo):

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

Luego crea un encabezado puente para tu proyecto Swift y luego inicializa tu Objective-C ViewController en tu código Swift, así (de nuevo, solo mi ejemplo):

var work : WorkaroundViewController = WorkaroundViewController()

¡Entonces has terminado! Déjame saber si te funciona ... Como dije, es feo, ¡pero funciona!


Aquí hay una solución menos fea, pero aún fea, inspirada por @tdun.

  1. Crea una clase para mantener tu apariencia de Objective-C. Para los propósitos de este ejemplo, vamos a llamarlo AppearanceBridger .
  2. Agregue esta clase a su encabezado de puente. Si no tiene un encabezado de puente, cree uno .
  3. Cree un método de clase en AppearanceBridger llamado +(void)setAppearance y coloque el código de apariencia de Objective-C en este método. Por ejemplo:

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

  1. En tu código Swift donde configuras la apariencia, llama a AppearanceBridger.setAppearance() y deberías estar listo!

Espero que esto funcione bien para las personas que lo ven.


Debería poder traducir la sintaxis de Objective-C sintaxis de Swift .

En breve, los métodos deberían declararse así:

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

Entonces puedes probar esto:

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

Todavía tengo que averiguar si esta es la manera más limpia de llamar a un método de clase en Swift .

Espero que esto ayude,


Esto se puede extender a cualquier clase que se ajuste al protocolo UIAppearance, no solo a UIViews. Así que aquí hay una versión más genérica:

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


He creado un repositorio para ustedes que quieren usar CocoaPods :

  1. Agregue esto en su Podfile :

    pod ''UIViewAppearanceSwift''

  2. Importar en tu clase:

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

  3. Referencia: https://github.com/levantAJ/UIViewAppearanceSwift


Parece que Swift (al menos a partir de Beta5) no puede admitirlo por razones desconocidas para mí. Quizás la función de idioma requerida todavía está en progreso, ya que solo puedo suponer que lo dejaron fuera de la interfaz por una buena razón. Como dijiste, de acuerdo con los documentos, todavía está disponible en ObjC. Realmente decepcionante


Puedes usar esto:

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

Edit: appearanceWhenContainedIn fue eliminado en Swift. Esta respuesta fue para la Beta 5 para cambiar la apariencia del texto de todos los botones de la barra.


ios 10 swift 3

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


Swift 4: iOS 9+

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