web-dev-qa-db-fra.com

Pouvez-vous donner des bordures UIStackView?

J'essaie de donner 5 variables UIStackViews distinctes dans mes frontières ViewController. J'ai donné à chacun d'eux une IBOutlet et les ai ensuite appelés dans viewDidLoad pour qu'ils utilisent la propriété layer mais en vain. N'est-il pas possible de définir des bordures de vues de pile, par programme? 

Code:

@IBOutlet weak var stackView1: UIStackView!
@IBOutlet weak var stackView2: UIStackView!
@IBOutlet weak var stackView3: UIStackView!
@IBOutlet weak var stackView4: UIStackView!
@IBOutlet weak var stackView5: UIStackView!

override func viewDidLoad() {
    super.viewDidLoad()

    stackView1.layer.borderWidth = 5
    stackView2.layer.borderWidth = 5
    stackView3.layer.borderWidth = 5
    stackView4.layer.borderWidth = 5
    stackView5.layer.borderWidth = 5   
}
21
pmoney13

Malheureusement, cela ne peut être fait. UIStackView est inhabituel en ce sens qu'il s'agit d'une vue "sans rendu" qui effectue la présentation (à l'aide de contraintes de disposition automatique) mais ne s'affiche pas d'elle-même. Il a une couche comme tous les UIViews, mais il est ignoré.

Voir le document Apple sous "Gestion de l'apparence de la vue de pile":

UIStackView est une sous-classe d'UIView non génératrice de rendu. Ce ne est pas fournir une interface utilisateur propre. Au lieu de cela, il gère simplement le fichier position et la taille de ses vues disposées. En conséquence, certaines propriétés (comme backgroundColor) n’ont aucun effet sur la vue de pile. De même, vous ne pouvez pas remplacer layerClass, drawRect: ou drawLayer: inContext:

23
Clafou

Il est possible de le faire en ayant des vues à l'intérieur de la pile, sous la forme de bordures. Cela peut représenter beaucoup de travail et certaines situations risquent de ne pas fonctionner ou d’être résolues de manière à ne pas en valoir la peine. Vous devrez imbriquer les vues de pile afin de pouvoir définir des bordures horizontales et verticales. Dans mon le post de blog Borders Stack Views je vais plus en détail à ce sujet. Mais fondamentalement, j'ai des vues régulières dont l'arrière-plan est défini sur la couleur de mon choix et je donne des contraintes de hauteur ou de largeur de 1 en fonction de la direction de l'axe de la vue de pile. Voici la hiérarchie complète d'une grille 2x2 intégrée dans le générateur d'interface:

 view hierarchy

Résultat dans ce résultat:

 enter image description here

Voici un lien vers mon dépôt github de cet exemple afin que vous puissiez voir le fichier de storyboard.

11
Korey Hinton

Vous pouvez incorporer stackView dans UIView, puis définir les bordures de cette vue (couleur, largeur, etc.), puis contraindre stackView à UIView comme haut, gauche, droite.

7
Filip Raj

Voici un morceau de code pratique que j'ai trouvé et utilisé:

extension UIView {
    func addTopBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:0,y: 0, width:self.frame.size.width, height:width)
        self.layer.addSublayer(border)
    }

    func addRightBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x: self.frame.size.width - width,y: 0, width:width, height:self.frame.size.height)
        self.layer.addSublayer(border)
    }

    func addBottomBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:0, y:self.frame.size.height - width, width:self.frame.size.width, height:width)
        self.layer.addSublayer(border)
    }

    func addLeftBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:0, y:0, width:width, height:self.frame.size.height)
        self.layer.addSublayer(border)
    }

    func addMiddleBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:self.frame.size.width/2, y:0, width:width, height:self.frame.size.height)
        self.layer.addSublayer(border)
    }
}

Utilisez simplement n'importe quelle vue comme celle-ci:

bottomControls.addMiddleBorderWithColor(color: buttonBorderColor, width: 3.0)

Source: Comment ajouter uniquement une bordure TOP sur un UIButton?

1
devpreneur

Je pense que le moyen le plus simple de le faire est de ne plus utiliser d’étiquettes ni de vues avec une hauteur/largeur égale à un pour représenter les bordures. C’est encore plus facile en utilisant l’attribut SPACING des vues de pile elles-mêmes. Il suffit de remplir votre pile et ses substances, puis d'espacer un pour l'empilement vertical externe, mais également d'un espacement pour les piles horizontales intérieures, vous obtenez un résultat parfait. Enfin, dans le but de donner une couleur spécifique aux bordures, j'ai maintenu cette vue en utilisant la vue de fond pour la vue externe stckview, elle a juste la même contrainte que la pile avec la couleur de fond que vous voulez pour les bordures. la pile, ça y est: D, veuillez vérifier les résultats comme dans l'image ci-jointe et laissez-moi savoir si quelque chose n'est pas clair  enter image description here

0
IsPha

Comme d'autres l'ont indiqué, vous ne pouvez pas le faire (pour plus de détails, voir la réponse de Clafou). 

Ce que vous pouvez faire, cependant, est d’incorporer votre vue de pile dans un autre UIView; apporter des modifications à la couche de UIView englobant.

0
Spencer Hall