web-dev-qa-db-fra.com

Comment créer un pourcentage de la largeur totale en utilisant autolayout?

Je dois créer trois colonnes dynamiques, chacune avec un pourcentage fixe de la largeur totale. Pas des tiers, mais des valeurs différentes. Par exemple, l'illustration suivante montre trois colonnes: la première de 42%, la seconde de 25% et la troisième de 33%.

Pour un contrôleur de vue de 600 pixels, ce serait respectivement 252, 150 et 198 pixels.

Toutefois, pour toutes les tailles d’affichage ultérieures (par exemple, iPhone 4 paysage (largeur 960) ou iPad 2 portrait (largeur 768)), je souhaite que les pourcentages relatifs soient identiques (et non les largeurs de pixels indiquées ci-dessus).

Y a-t-il un moyen de faire cela en utilisant Storyboards (c'est-à-dire sans code)? Je peux le faire facilement dans le code, mais mon objectif est d’insérer le plus possible cette logique d’affichage dans le Storyboard.

enter image description here

106
Jeffrey Berthiaume

Si, comme vous le dites, vous savez comment le faire en code, vous savez déjà comment le faire dans le scénarimage. Ce sont exactement les mêmes contraintes, mais vous les créez visuellement plutôt que dans le code.

  1. Sélectionnez à la fois une vue et son aperçu.

  2. Choisissez Editeur -> Épinglette -> Largeurs De même, pour que la largeur soit égale à la largeur de la vue d'ensemble (en fait, la boîte de dialogue contextuelle "Épinglette" située au bas du canevas fonctionne mieux ici).

  3. Modifiez la contrainte et définissez le multiplicateur sur la fraction souhaitée, par exemple. 0,42. Et aussi pour les autres points de vue.

195
matt

En tant que Apple introduit IStackView, cela a rendu le travail beaucoup plus facile.

Méthode 1: Utiliser Nib/StoryBoard:

Vous devez simplement ajouter trois vues dans le générateur d'interface et les incorporer dans stackview

Xcode ► Editeur ► Intégrer dans ► StackView

enter image description here

Sélectionnez stackView & donnez une contrainte avec une avance, une fin, une hauteur maximale et égale avec safeArea

Cliquez sur pour attribuer une zone à l'inspecteur & . Définissez StackView horizontal & distribution pour un remplissage proportionnel

[enter image description here

Indiquez la contrainte de trois vues avec les côtés avant, arrière, haut, bas. enter image description here

Méthode 2: Programmation:

import UIKit
class StackViewProgramatically: UIViewController {
    var propotionalStackView: UIStackView!
    ///Initially defining three views
    let redView: UIView = {
        let view = UIView()//taking 42 % initially
        view.frame = CGRect(x: 0, y: 0, width: 42 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .red
        return view
    }()

    let greenView: UIView = {
        let view = UIView()//taking 42* initially
        view.frame = CGRect(x: 42 * UIScreen.main.bounds.width/100, y: 0, width: 25 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .green
        return view
    }()
    let blueView: UIView = {
        let view = UIView()//taking 33*initially
        view.frame = CGRect(x: 67 * UIScreen.main.bounds.width/100, y: 0, width: 33 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .blue
        return view
    }()

    ///Changing UIView frame to supports landscape mode.
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        DispatchQueue.main.async {
            self.redView.frame = CGRect(x: 0, y: 0, width: 42 * self.widthPercent, height: self.screenHeight)
            self.greenView.frame = CGRect(x: 42 * self.widthPercent, y: 0, width: 25 * self.widthPercent, height: self.screenHeight)
            self.blueView.frame = CGRect(x: 67 * self.widthPercent, y: 0, width: 33 * self.widthPercent, height: self.screenHeight)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        //Adding subViews to the stackView
        propotionalStackView = UIStackView()
        propotionalStackView.addSubview(redView)
        propotionalStackView.addSubview(greenView)
        propotionalStackView.addSubview(blueView)
        propotionalStackView.spacing = 0
        ///setting up stackView
        propotionalStackView.axis = .horizontal
        propotionalStackView.distribution = .fillProportionally
        propotionalStackView.alignment = .fill
        view.addSubview(propotionalStackView)
    }
}
//MARK: UIscreen helper extension
extension NSObject {

    var widthPercent: CGFloat {
        return UIScreen.main.bounds.width/100
    }

    var screenHeight: CGFloat {
        return UIScreen.main.bounds.height
    }
}

Sortie:

Fonctionne avec paysage et portrait

enter image description hereenter image description here

Projet de démonstration - https://github.com/janeshsutharios/UIStackView-with-constraints

https://developer.Apple.com/videos/play/wwdc2015/218/

9
Jack

Je pense que cela peut être expliqué plus en détail afin de pouvoir l'appliquer plus facilement à un nombre quelconque de vues nécessitant des présentations à pourcentage fixe dans un super aperçu.

Vue la plus à gauche

  • Ancré à SuperView.Leading
  • Définit son pourcentage fixe en tant que multiplicateur sur le SuperView.Height

Vues intermédiaires

  • Définit son pourcentage fixe en tant que multiplicateur sur le SuperView.Height
  • Épingle son left à la droite de son voisin

Vue la plus à droite

  • Ne définit pas un pourcentage fixe (c'est le reste de la vue disponible)
  • Épingle son left à la droite de son voisin
  • Épingle sa right à SuperView.Trailing

Toutes les vues

  • Définissez leurs hauteurs non fixées en les ancrant à Top Layout Guide.Top et Top Layout Guide.bottom. Dans la réponse ci-dessus, il est noté que cela peut également être fait en réglant une hauteur égale à la vue voisine.
4
JuJoDi