J'essaie de convertir mon application dans la langue Swift.
J'ai cette ligne de code:
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil]
setTitleTextAttributes:textDictionary
forState:UIControlStateNormal];
Comment le convertir en Swift?
Dans documentation d'Apple , cette méthode n'existe pas.
Si vous ciblez iOS 9+ (à partir de Xcode 7 b1), il existe une nouvelle méthode dans le protocole UIAppearance
qui n'utilise pas de variables:
static func appearanceWhenContainedInInstancesOfClasses(containerTypes: [AnyObject.Type]) -> Self
Qui peut être utilisé comme suit:
UITextField.appearanceWhenContainedInInstancesOfClasses([MyViewController.self]).keyboardAppearance = .Light
Si vous devez toujours prendre en charge iOS 8 ou une version antérieure, utilisez la réponse originale suivante à cette question.
Ces méthodes ne sont pas disponibles pour Swift car les méthodes Obj-C varargs ne sont pas compatibles avec Swift (voir http: //www.openradar. moi/17302764 ).
J'ai écrit une solution de contournement non variadique qui fonctionne dans Swift (j'ai répété la même méthode pour UIBarItem
, qui ne descend pas 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
Assurez-vous juste de #import "UIAppearance+Swift.h"
dans votre en-tête de pontage.
Ensuite, pour appeler de Swift (par exemple):
# 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"
J'utilise une catégorie basée sur la réponse d'Alex pour spécifier plusieurs conteneurs. Ceci est une solution de contournement jusqu'au Apple supporte officiellement appearanceWhenContainedIn
dans 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
Puis ajouter #import "UIAppearance+Swift.h"
à votre en-tête de pontage.
À utiliser depuis Swift :
TextField.appearanceWhenContainedWithin([MyViewController.self, TableViewController.self]).keyboardAppearance = .Light
C'était bien si je pouvais trouver un moyen d'utiliser CVarArgType , mais je n'ai trouvé aucune solution propre.
Voici une solution de contournement moins laide, mais toujours laide, inspirée de @tdun.
AppearanceBridger
.AppearanceBridger
nommée +(void)setAppearance
et insérez le code d'apparence d'Objective-C dans cette méthode. Par exemple:
+ (void)setAppearance {
[[UIView appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setBackgroundColor:[UIColor whiteColor]];
}
AppearanceBridger.setAppearance()
] _ et vous devriez être prêt à partir!J'espère que cela fonctionne bien pour les personnes qui le voient.
Cela peut être étendu à toute classe conforme au protocole UIAppearance - pas seulement à UIViews. Alors, voici une version plus générique:
IAppearance + Swift.h
#import <UIKit/UIKit.h>
@interface NSObject (UIAppearance_Swift)
+ (instancetype)appearanceWhenContainedWithin:(Class<UIAppearanceContainer>)containerClass;
@end
IAppearance + 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
Voici une solution de contournement laide que j'ai utilisé ....
Créez simplement une classe tactile Objective-C Cocoa (UIViewController), nommée comme vous le souhaitez.
J'ai nommé le mien WorkaroundViewController
...
Maintenant dans (WorkaroundViewController.m
):
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
Exécutez le code d'apparence d'Objective-C pour .appearanceWhenContainedIn()
(voici mon exemple):
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Avenir-Light" size:16.0f]}];
Puis créez un en-tête de pontage pour votre Swift, puis initialisez votre ViewController Objective-C dans votre Swift, comme ceci ( encore, juste mon exemple):
var work : WorkaroundViewController = WorkaroundViewController()
Alors vous avez fini! Faites-moi savoir si cela fonctionne pour vous ... Comme je l'ai dit, c'est moche, mais ça marche!
J'ai créé un dépôt pour vous qui voulez utiliser CocoaPods
:
Ajoutez ceci dans votre Podfile
:
pod 'UIViewAppearanceSwift'
Importer dans votre classe:
import UIViewAppearanceSwift
func layout() {
UINavigationBar.appearanceWhenContainedWithin(MFMailComposeViewController.self).barStyle = .Black
UIBarButtonItem.appearanceWhenContainedWithin(UISearchBar.self).setTitleTextAttributes([NSFontAttributeName: UIFont.systemFontOfSize(15)], forState: UIControlState.Normal)
}
Référence: https://github.com/levantAJ/UIViewAppearanceSwift
Swift 4: iOS 9 +
UIProgressView.appearance(whenContainedInInstancesOf: [LNPopupBar.self]).tintColor = .red
Il semble que Swift (du moins à partir de Beta5) ne soit pas en mesure de le prendre en charge pour des raisons inconnues. Peut-être que la fonctionnalité linguistique requise est toujours en cours, car je ne peux que présumer qu'ils l'ont laissée Comme vous l'avez dit, selon la documentation, il est toujours disponible dans ObjC. Vraiment décevant.