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
.
Juste au cas où quelqu'un d'autre viendrait ici pour savoir comment cela peut être fait par programme, voici comment vous le faites:
Effectuez une contrainte de hauteur dans IB sur la vue souhaitée et définissez la constante sur 1.
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:
onePixelViewHeightConstraint.constant = 1/UIScreen.main.scale//enforces it to be a true 1 pixel line
self.onePixelViewHeightConstraint.constant = 1.f/[UIScreen mainScreen].scale;//enforces it to be a true 1 pixel line
Prendre plaisir
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
et définissez sa classe sur HairlineConstraint
.
Terminé.
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.
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.
Accédez à ses propriétés et définissez la valeur.
Dans le cas ci-dessus, il affichera une vue avec une hauteur de 1 px sur les appareils 1x, 2x et 3x.
Dans Swift:
@IBOutlet var hairlineConstraint: NSLayoutConstraint! {
didSet {
hairlineConstraint.constant = 1 / UIScreen.mainScreen().scale
}
}
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).
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
}
}
}
}
Semble que ce n'est pas possible, il faut le faire par programmation ou créer une vue personnalisée.
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>