web-dev-qa-db-fra.com

iOS - Détecter les classes de taille actuelles sur viewDidLoad

Je travaille avec Layout adaptatif sur iOS 8 et je veux savoir exactement quelles sont les classes de taille sur viewDidLoad. Des idées à ce sujet?

33
user3193307

Depuis iOS 8 IViewController adopte le protocole ITraitEnvironment. Ce protocole déclare une propriété nommée traitCollection qui est de type ITraitCollection. Vous pouvez donc accéder à la propriété traitCollection simplement en utilisant self.traitCollection

ITraitCollection a deux propriétés auxquelles vous souhaitez accéder nommées horizontalSizeClass et verticalSizeClass L'accès à ces propriétés renvoie un NSInteger. L'énumération qui définit les valeurs renvoyées est déclarée dans la documentation officielle comme suit - (cela pourrait éventuellement être ajouté à l'avenir!)

typedef NS_ENUM (NSInteger, UIUserInterfaceSizeClass {
   UIUserInterfaceSizeClassUnspecified = 0,
   UIUserInterfaceSizeClassCompact     = 1,
   UIUserInterfaceSizeClassRegular     = 2,
};

Ainsi, vous pouvez obtenir la classe et utiliser, par exemple, un commutateur pour déterminer la direction de votre code. Un exemple pourrait être -

NSInteger horizontalClass = self.traitCollection.horizontalSizeClass;
NSInteger verticalCass = self.traitCollection.verticalSizeClass;

switch (horizontalClass) {
    case UIUserInterfaceSizeClassCompact :
        // horizontal is compact class.. do stuff...
        break;
    case UIUserInterfaceSizeClassRegular :
        // horizontal is regular class.. do stuff...
        break;
    default :
        // horizontal is unknown..
        break;
}
// continue similarly for verticalClass etc.
68
Bamsworld

Quelques trucs utiles pour Swift 4:

UIViewController Extension pour récupérer les classes en tant que Tuple.

extension UIViewController {
  func sizeClass() -> (UIUserInterfaceSizeClass, UIUserInterfaceSizeClass) {
      return (self.traitCollection.horizontalSizeClass, self.traitCollection.verticalSizeClass)
  }
}

Exemple d'instruction Switch pour consommer la fonction:

    switch self.sizeClass() {
    case (UIUserInterfaceSizeClass.unspecified, UIUserInterfaceSizeClass.unspecified):
        print("Unknown")
    case (UIUserInterfaceSizeClass.unspecified, UIUserInterfaceSizeClass.compact):
        print("Unknown width, compact height")
    case (UIUserInterfaceSizeClass.unspecified, UIUserInterfaceSizeClass.regular):
        print("Unknown width, regular height")
    case (UIUserInterfaceSizeClass.compact, UIUserInterfaceSizeClass.unspecified):
        print("Compact width, unknown height")
    case (UIUserInterfaceSizeClass.regular, UIUserInterfaceSizeClass.unspecified):
        print("Regular width, unknown height")
    case (UIUserInterfaceSizeClass.regular, UIUserInterfaceSizeClass.compact):
        print("Regular width, compact height")
    case (UIUserInterfaceSizeClass.compact, UIUserInterfaceSizeClass.compact):
        print("Compact width, compact height")
    case (UIUserInterfaceSizeClass.regular, UIUserInterfaceSizeClass.regular):
        print("Regualr width, regular height")
    case (UIUserInterfaceSizeClass.compact, UIUserInterfaceSizeClass.regular):
        print("Compact width, regular height")
    }

Édition/ajout:

Si vous essayez d'accéder à la collection de traits au début du cycle de vie de UIViewController, ils pourraient tous être UIUserInterfaceSizeClass.unspecified.

Cela peut être pénible s'il vous arrive de faire des contraintes dans le code.

Je recommande d'accéder au .traitCollection à partir de l'objet partagé UIScreen.

UIScreen.main.traitCollection

Ou encore plus utile:

UIScreen.main.traitCollection.userInterfaceIdiom
13
Jon Vogel

C'est bien pour tester/déboguer:

let sizeClasses = ["Unspecified", "Compact", "Regular"]
print("SizeClass w:\(sizeClasses[traitCollection.horizontalSizeClass.rawValue]) h:\(sizeClasses[traitCollection.verticalSizeClass.rawValue])")
2
coco

Vous pouvez aussi le faire comme ça dans Swift 5

enum DeviceTraitStatus {
    ///IPAD and others: Width: Regular, Height: Regular
    case wRhR
    ///Any IPHONE Portrait Width: Compact, Height: Regular
    case wChR
    ///IPHONE Plus/Max Landscape Width: Regular, Height: Compact
    case wRhC
    ///IPHONE landscape Width: Compact, Height: Compact
    case wChC

    static var current:DeviceTraitStatus{

        switch (UIScreen.main.traitCollection.horizontalSizeClass, UIScreen.main.traitCollection.verticalSizeClass){

        case (UIUserInterfaceSizeClass.regular, UIUserInterfaceSizeClass.regular):      
            return .wRhR
        case (UIUserInterfaceSizeClass.compact, UIUserInterfaceSizeClass.regular):
            return .wChR
        case (UIUserInterfaceSizeClass.regular, UIUserInterfaceSizeClass.compact):
            return .wRhC
        case (UIUserInterfaceSizeClass.compact, UIUserInterfaceSizeClass.compact):
            return .wChC
        default:
            return .wChR

        }

    }

}

Le principal avantage est qu'il peut être utilisé non seulement à partir d'une classe UIViewController dépendante et que la méthode statique peut aller dans une classe Helper. Vous pouvez donc faire quelque part dans votre code:

let textSize:CGFloat = DeviceTraitStatus.current == .wRhR ? 18:14
0
Reimond Hill