Dans iOS 8, nous pouvons concevoir une disposition d'interface utilisateur différente pour chaque classe de taille. Le problème auquel je suis confronté est que j'ai conçu une mise en page pour Compact Width et Regular Height (classe de taille pour tous les iPhones en mode portrait), mais je souhaite que la taille de la police des étiquettes soit plus petite pour les appareils de 3,5 et 4 pouces (iPhone 4 et 5 ), puis relativement plus gros pour 4,7 pouces (iPhone 6) et plus grand pour les appareils 5,5 pouces (iPhone 6 Plus). J'ai cherché mais je suis incapable de trouver une solution pour définir une taille de police différente pour différents périphériques dans la même classe de taille.
Edit : Je ne le recommande plus. Cette approche ne s'adapte pas bien lorsque de nouveaux appareils sortent. Utilisez une combinaison de tailles de police dynamiques et de polices spécifiques aux classes de taille.
Supposons qu'un nouveau modèle d'iPhone apparaisse. Si vous utilisez les classes de disposition et de taille automatiques, vous n'avez pas à résoudre toutes les contraintes manuellement pour rendre votre application compatible avec ce nouvel appareil. Cependant, vous pouvez toujours définir la taille de la police de la UILabel
à l'aide du code suivant:
if UIScreen.mainScreen().bounds.size.height == 480 {
// iPhone 4
label.font = label.font.fontWithSize(20)
} else if UIScreen.mainScreen().bounds.size.height == 568 {
// IPhone 5
label.font = label.font.fontWithSize(20)
} else if UIScreen.mainScreen().bounds.size.width == 375 {
// iPhone 6
label.font = label.font.fontWithSize(20)
} else if UIScreen.mainScreen().bounds.size.width == 414 {
// iPhone 6+
label.font = label.font.fontWithSize(20)
} else if UIScreen.mainScreen().bounds.size.width == 768 {
// iPad
label.font = label.font.fontWithSize(20)
}
Je le gère dans un projet dans Swift 3+ en utilisant une classe UILabel Custom, une extension UILabel et une extension UIDevice comme solution générique.
UIDevice extension pour obtenir screenType
:
public extension UIDevice {
var iPhone: Bool {
return UIDevice().userInterfaceIdiom == .phone
}
enum ScreenType: String {
case iPhone4
case iPhone5
case iPhone6
case iPhone6Plus
case iPhoneX
case Unknown
}
var screenType: ScreenType {
guard iPhone else { return .Unknown}
switch UIScreen.main.nativeBounds.height {
case 960:
return .iPhone4
case 1136:
return .iPhone5
case 1334:
return .iPhone6
case 2208:
return .iPhone6Plus
case 2436:
return .iPhoneX
default:
return .Unknown
}
}
}
Voici l’extension UILabel qui utilise screenType
pour ajuster la taille de la police. La méthode adjustsFontSizeToFitDevice
pourrait également être ajoutée à la classe personnalisée UILabel, mais je l'ai mise à l'extension UILabel pour la rendre accessible à partir de tous les types d'instances UILabel.
La constante "2" utilisée dans la méthode adjustsFontSizeToFitDevice
peut être modifiée pour n’importe quel nombre souhaité. Ma logique est de considérer l'iPhone 6/7/8 comme résolution par défaut et de donner une taille de police appropriée (en Storyboard) à chaque étiquette pour cette résolution. Ensuite, j'ajoute 2 points pour iPhone X et iPhone 6/7/8 Plus, tandis que je soustrais 2 points pour iPhone 4/5.
extension UILabel {
func adjustsFontSizeToFitDevice() {
switch UIDevice().screenType {
case .iPhone4, .iPhone5:
font = font.withSize(font.pointSize - 2)
break
case .iPhone6Plus, .iPhoneX:
font = font.withSize(font.pointSize + 2)
break
default:
font = font.withSize(font.pointSize)
}
}
}
Enfin, une classe personnalisée UILabel pour appliquer un ajustement de police à toutes les étiquettes sous-classées à partir de MyCustomLabel
.
class MyCustomLabel: UILabel {
// MARK: - Life Cycle Methods
override func awakeFromNib() {
super.awakeFromNib()
adjustsFontSizeToFitDevice()
}
}
Utilisation: Dans Storyboard, sous-classe toutes les instances de UILabel de MyCustomLabel
dont la taille de la police doit être ajustée en fonction de la taille du périphérique.
Vous pouvez obtenir l'effet désiré comme ci-dessous.
Usage :
au lieu d'utiliser 14 comme taille de police, vous pouvez utiliser 14.fontSize
, il sera modifié en fonction du périphérique, cela dépend de votre valeur delta.
Pas besoin d'ajouter des conditions chaque fois dans le code. Une seule fois comme ci-dessous.
Usage: UIFont.font_medium(12.fontSize)
Extension UIFont:
extension UIFont {
class func font_medium(_ size : CGFloat) -> UIFont {
return UIFont(name: "EncodeSans-Medium", size: size)!;
}
}
UIDevice Extension:
extension UIDevice {
enum DeviceTypes {
case iPhone4_4s
case iPhone5_5s
case iPhone6_6s
case iPhone6p_6ps
case after_iPhone6p_6ps
}
static var deviceType : DeviceTypes {
switch UIScreen.main.height {
case 480.0:
return .iPhone4_4s
case 568.0:
return .iPhone5_5s
case 667.0:
return .iPhone6_6s
case 736.0:
return .iPhone6p_6ps
default:
return .after_iPhone6p_6ps
}
}
}
Int Extension:
extension Int{
var fontSize : CGFloat {
var deltaSize : CGFloat = 0;
switch (UIDevice.deviceType) {
case .iPhone4_4s,
.iPhone5_5s :
deltaSize = -1;
case .iPhone6_6s :
deltaSize = 2;
case .iPhone6p_6ps :
deltaSize = 2;
default:
deltaSize = 0;
}
let selfValue = self;
return CGFloat(selfValue) + deltaSize;
}
}
Deux manières:
1) Créez manuellement une méthode dans un délégué d'application, partagez son objet et sa méthode d'appel.
par exemple :
var device = UIDevice.currentDevice().model
if (device == "iPhone" || device == "iPhone Simulator" || device == "iPod touch")
{
labelboarder.frame = CGRectMake(0,self.usernameTF.frame.height-10, self.usernameTF.frame.width, 1)
labelboarder1.frame = CGRectMake(0,self.usernameTF.frame.height-10, self.usernameTF.frame.width,1)
}
else
{
labelboarder.frame = CGRectMake(0,self.usernameTF.frame.height, 500, 1)
labelboarder1.frame = CGRectMake(0,self.usernameTF.frame.height, 500,1)
}
2) Sur chaque élément de l'interface utilisateur, accédez à l'inspecteur d'attributs, déclarez une police.
(Un signe + est visible à gauche du champ Taille de la police. Cliquez dessus, sélectionnez la classe de taille correspondante et déclarez la taille de la police.)
La deuxième option est pratique pour moi. Bon codage!
Au lieu d'écrire du code pour chaque étiquette, faites simplement étendre votre classe d'étiquettes avec votre classe d'étiquettes personnalisée comme ci-dessous et elle sera automatiquement mise à l'échelle en fonction du facteur de mise à l'échelle de la résolution du périphérique:
#define SCALE_FACTOR_H ( [UIScreen mainScreen].bounds.size.height / 568 )
CustomLabel.h
#import <UIKit/UIKit.h>
@interface CustomLabel : UILabel
@end
CustomLabel.m
#import "CustomLabel.h"
@implementation CustomLabel
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (id)initWithCoder:(NSCoder *)aDecoder {
if( (self = [super initWithCoder:aDecoder]) ){
[self layoutIfNeeded];
[self configurefont];
}
return self;
}
- (void) configurefont {
CGFloat newFontSize = (self.font.pointSize * SCALE_FACTOR_H);
self.font = [UIFont fontWithName:self.font.fontName size:newFontSize];
}
@end
Créer comme ça,
#define VIEWHEIGHT ([[UIScreen mainScreen] bounds].size.height)
#define VIEWWIDTH ([[UIScreen mainScreen] bounds].size.width)
#define FONTNAME_LIGHT @"AppleSDGothicNeo-Regular"
#define FONTNAME_BOLD @"AppleSDGothicNeo-Bold"
#define LFONT_16 [UIFont fontWithName:FONTNAME_LIGHT size:16]
après cela, si vous voulez changer la police de l'étiquette, nous pouvons écrire une simple casse Switch
switch ((VIEWHEIGHT == 568)?1:((VIEWHEIGHT == 667)?2:3)) {
case 1:{
boldFont = BFONT_16;
}
break;
case 2:{
privacyFont = LFONT_18;
boldFont = BFONT_18;
}
break;
default:{
privacyFont = LFONT_20;
boldFont = BFONT_20;
}
break;
}
Swift Version
func isPhoneDevice() -> Bool {
return UIDevice.current.userInterfaceIdiom == .phone
}
func isDeviceiPad() -> Bool {
return UIDevice.current.userInterfaceIdiom == .pad
}
func isPadProDevice() -> Bool {
let SCREEN_WIDTH = Float(UIScreen.main.bounds.size.width)
let SCREEN_HEIGHT = Float(UIScreen.main.bounds.size.height)
let SCREEN_MAX_LENGTH: Float = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
return UIDevice.current.userInterfaceIdiom == .pad && SCREEN_MAX_LENGTH == 1366.0
}
func isPhoneXandXSDevice() -> Bool {
let SCREEN_WIDTH = CGFloat(UIScreen.main.bounds.size.width)
let SCREEN_HEIGHT = CGFloat(UIScreen.main.bounds.size.height)
let SCREEN_MAX_LENGTH: CGFloat = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
return UIDevice.current.userInterfaceIdiom == .phone && SCREEN_MAX_LENGTH == 812.0
}
func isPhoneXSMaxandXRDevice() -> Bool {
let SCREEN_WIDTH = CGFloat(UIScreen.main.bounds.size.width)
let SCREEN_HEIGHT = CGFloat(UIScreen.main.bounds.size.height)
let SCREEN_MAX_LENGTH: CGFloat = fmax(SCREEN_WIDTH, SCREEN_HEIGHT)
return UIDevice.current.userInterfaceIdiom == .phone && SCREEN_MAX_LENGTH == 896.0
}
C'est comme ça que je l'ai fait. C'est écrit dans Swift 4 :)
enum DeviceSize {
case big, medium, small
}
protocol Fontadjustable {
var devicetype: DeviceSize { get }
func adjustFontSizeForDevice()
}
extension UILabel: Fontadjustable {
var devicetype: DeviceSize {
switch UIScreen.main.nativeBounds.height {
case 1136:
return .small
case 1334:
return .medium
case 2208:
return .big
case 2436:
return .big
default:
return .big
}
}
func adjustFontSizeForDevice() {
switch self.devicetype {
case .small:
self.font = font.withSize(font.pointSize)
case .medium:
self.font = font.withSize(font.pointSize + 5)
case .big:
self.font = font.withSize(font.pointSize + 10)
}
}
}
USAGE: myawesomeLabel.adjustFontSizeForDevice()