web-dev-qa-db-fra.com

Comment créer une ligne 1px dans Interface Builder?

Remarque, je cherche à créer une ligne 1px, pas une ligne 1pt. Cela signifie qu'il devrait être de 1px quelle que soit l'échelle de l'écran (donc 0,5 pt sur les appareils Retina).

Je peux le faire par programme, mais puis-je le faire dans Interface Builder? Par exemple, je ne peux pas définir une UIView pour avoir une hauteur inférieure à 1.

Si je peux le faire dans IB, je n'ai pas à déclarer de sortie et à définir manuellement le cadre dans awakeFromNib.

32
i_am_jorf

Juste au cas où quelqu'un d'autre viendrait ici pour savoir comment cela peut être fait par programme, voici comment vous le faites:

Générateur d'interface

Effectuez une contrainte de hauteur dans IB sur la vue souhaitée et définissez la constante sur 1.

enter image description here

Ensuite, vous devrez CTRL + glisser depuis la contrainte dans votre vue personnalisée ou ViewController.

Chaque fois que le Xib est chargé, que ce soit dans awakeFromNib ou viewDidLoad, vous allez définir la constante de la contrainte à l'échelle de l'affichage:

Swift

onePixelViewHeightConstraint.constant = 1/UIScreen.main.scale//enforces it to be a true 1 pixel line

Objectif c

self.onePixelViewHeightConstraint.constant = 1.f/[UIScreen mainScreen].scale;//enforces it to be a true 1 pixel line

Prendre plaisir

50
Daniel Galasko

J'ai créé la sous-classe NSLayoutConstraint:

class HairlineConstraint: NSLayoutConstraint {
    override func awakeFromNib() {
        super.awakeFromNib()

        self.constant = 1.0 / UIScreen.main.scale
    }
}

Ensuite, créez simplement votre vue dans le générateur d'interface, ajoutez une contrainte de hauteur

Custom view with height constraint

et définissez sa classe sur HairlineConstraint.

Set constraint class

Terminé.

35

En créant cette minuscule sous-classe de NSLayoutConstraint je peux maintenant ajouter des lignes 1px dans IB:

@implementation NSLayoutConstraintHairline

-(void)awakeFromNib
{
    [super awakeFromNib];
    if ( self.constant == 1 ) self.constant = 1/[UIScreen mainScreen].scale;
}

@end

Toute contrainte avec une valeur de 1 peut être définie sur la classe NSLayoutConstraintHairline pour que la constante soit effectivement 1px au lieu de 1pt.

Si vous décidez de changer la constante en une autre valeur, cela fonctionnera comme n'importe quelle autre contrainte.

27
mvds

Avec xCode 6 et introduction de @IBInspectable et @IBDesignable mots-clés c'est certainement possible et assez simple. Pas besoin de sous-classe/sortie quoi que ce soit.

Vous pouvez faire une extension (catégorie) pour NSLayoutConstraint avec le code suivant (Swift):

extension NSLayoutConstraint {

    @IBInspectable var preciseConstant: Int {
        get {
            return Int(constant * UIScreen.mainScreen().scale)
        }
        set {
            constant = CGFloat(newValue) / UIScreen.mainScreen().scale
        }
    }
}

Ensuite, vous pouvez choisir la contrainte nécessaire dans votre IB.

IB objects navigator part

Accédez à ses propriétés et définissez la valeur.

IB properties of NSLayoutConstraint

Dans le cas ci-dessus, il affichera une vue avec une hauteur de 1 px sur les appareils 1x, 2x et 3x.

26
Nevs12

Dans Swift:

@IBOutlet var hairlineConstraint: NSLayoutConstraint! {
    didSet {
        hairlineConstraint.constant = 1 / UIScreen.mainScreen().scale
    }
}
13
Rudolf Adamkovič

EDIT: Cette réponse concernait uniquement les appareils @ 2x. A cette époque, @ 3x n'était pas encore sur le marché!

De nos jours, la réponse de @mdvs Semble être la plus propre.


Il est difficile de créer une ligne 1px en IB, même pour les appareils à rétine uniquement. Enfin, je l'ai atteint en utilisant le User Defined Runtime Attributes.

Voici une capture d'écran pour définir la contrainte de hauteur à 0,5 px (qui est de 1 px sur les appareils rétiniens).

8
Michał Zygar

Sur la base de la réponse de @ Nevs12 et de ses commentaires, je pense qu'il est plus logique d'utiliser une telle chose:

extension NSLayoutConstraint {
    @IBInspectable var usePixels: Bool {
        get {
            return false // default Value
        }
        set {
            if newValue {
                constant = constant / UIScreen.mainScreen().scale
            }
        }
    }
}
4
farzadshbfn

Semble que ce n'est pas possible, il faut le faire par programmation ou créer une vue personnalisée.

2
i_am_jorf

Vous pouvez le faire dans un fichier .xib. Modifiez-le simplement en tant que texte et définissez constant = "0.5" au lieu de "1" dans la contrainte de hauteur de votre vue

<constraints>
<constraint firstAttribute="height" constant="0.5" id="xUN-dm-ggj"/>
</constraints>

Dans Interface Builder

1
Andrey Snetkov