2016-04-03 1 views
0

I ont une classe ViewController qui a une variable textField, qui est configuré lorsqu'il est défini dans le procédé de la viewDidLoadViewController.contraintes Mise à jour autolayout selon l'orientation

class ViewController: UIViewController { 

    weak var textField: UITextField! { 
     didSet { 
      textField.delegate = self 
      textField.placeholder = "Enter Text" 
      view.addSubview(textField) 
      view.addConstraint(NSLayoutConstraint(item: textField, attribute: .Width, relatedBy: .Equal, toItem: view, attribute: .Width, multiplier: 0.80, constant: 0)) 
      view.addConstraint(NSLayoutConstraint(item: textField, attribute: .Height, relatedBy: .Equal, toItem: view, attribute: .Height, multiplier: 0.05, constant: 0)) 
      view.addConstraint(NSLayoutConstraint(item: textField, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1, constant: 0)) 
      view.addConstraint(NSLayoutConstraint(item: textField, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0)) 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     textField = UITextField() 
    } 
} 

Un ensemble de contraintes de mise en page automatique est ajouté à la vue. Je veux que ce champ de texte soit centré au milieu (.CenterX et .CenterY), à 80% (5%) de la largeur (hauteur) de view calculée en mode portrait du ViewController.

Si l'orientation du dispositif (UIDevice.currentDevice().orientation) est tourné dans orientation paysage, ou présenté d'une orientation paysage, je veux la largeur (hauteur) reste la même que pour l'orientation portrait.

Modification du attribute pour le toItem dans:

view.addConstraint(NSLayoutConstraint(item: textField, attribute: .Height, relatedBy: .Equal, toItem: view, attribute: .Height, multiplier: 0.05, constant: 0)) 

à:

attribute: (UIDeviceOrientationIsPortrait(UIDevice.currentDevice().orientation) ? .Height : .Width) 

Ne pas faire l'affaire comme je suppose que le textField ne reçoit pas (re) définir quand le dispositif bascule l'orientation. En outre, cette vérification semble un peu grumeleuse pour Swift. Est-ce que je manque un truc avec autolayout?

Répondre

1

En fait, le problème dans votre code est que vous n'avez pas défini la translatesAutoresizingMaskIntoConstraints de textField à false, chaque fois que vous voulez utiliser des contraintes d'auto-mise en page, vous devez définir translatesAutoresizingMaskIntoConstraints d'une vue de false.

J'ai mis à jour votre code, regardez-le et ça fonctionne bien.

class ViewController: UIViewController, UITextFieldDelegate {  
    weak var textField: UITextField! { 
     didSet { 
      textField.delegate = self 
      textField.placeholder = "Enter Text" 
      view.addSubview(textField) 
      // to see the size of textField 
      textField.backgroundColor = UIColor.purpleColor() 

      textField.translatesAutoresizingMaskIntoConstraints = false 

      view.addConstraint(NSLayoutConstraint(item: textField, attribute: .Width, relatedBy: .Equal, toItem: view, attribute: .Width, multiplier: 0.80, constant: 0)) 
      view.addConstraint(NSLayoutConstraint(item: textField, attribute: .Height, relatedBy: .Equal, toItem: view, attribute: .Height, multiplier: 0.05, constant: 0)) 
      view.addConstraint(NSLayoutConstraint(item: textField, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1, constant: 0)) 
      view.addConstraint(NSLayoutConstraint(item: textField, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0)) 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     textField = UITextField() 

    } 
} 
+0

Bon endroit - merci. – Alex

+0

@Alex Votre bienvenue, Si vous voulez plus de façon facile de gérer la contrainte par programme alors jetez un oeil -https: //github.com/keshavvishwkarma/KVConstraintExtensionsMaster –

+0

Je ne suis toujours pas sûr si la spécification des contraintes dans un pourcentage relatif est un facteur meilleure approche? Par conséquent, vos sous-vues sont indépendantes du modèle iPhone, par exemple. Je suppose que c'est similaire à CSS. Des pensées à ce sujet? Merci. – Alex

0

Une solution serait d'obtenir les coordonnées fixe les limites de l'écran (iOS> = 8) et d'ajuster les deux premières contraintes de façon appropriée:

class ViewController: UIViewController, UITextFieldDelegate { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let textField = UITextField() 
     textField.translatesAutoresizingMaskIntoConstraints = false 
     textField.delegate = self 
     textField.placeholder = "Enter Text" 
     view.addSubview(textField) 

     textField.backgroundColor = UIColor.redColor() 
     textField.textAlignment = .Center 

     let fixedScreenBounds = UIScreen.mainScreen().fixedCoordinateSpace.bounds 

     NSLayoutConstraint.activateConstraints([ 
      NSLayoutConstraint(item: textField, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 0, constant: 0.8*fixedScreenBounds.width), 
      NSLayoutConstraint(item: textField, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 0, constant: 0.05*fixedScreenBounds.height), 
      NSLayoutConstraint(item: textField, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1, constant: 0), 
      NSLayoutConstraint(item: textField, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0) 
      ]) 
    } 
} 

De plus, sachez que, puisque vous créez le champ de texte Dans le code et vous souhaitez utiliser autolayout, vous devez définir son translatesAutoresizingMaskIntoConstraints sur false.