ios - trait - ¿Cómo creo una línea de 1px en Interface Builder?
vary for traits xcode 9 (10)
Tenga en cuenta que estoy buscando hacer una línea de 1px, no una línea de 1pt. Lo que significa que debe ser 1px independientemente de la escala de la pantalla (por lo tanto, 0.5pt en dispositivos Retina).
Puedo hacer esto programáticamente, pero ¿puedo hacerlo en Interface Builder? Por ejemplo, no puedo configurar una UIView para que tenga una altura inferior a 1.
Si puedo hacerlo en IB, entonces no tengo que declarar una toma de corriente y configurar manualmente el cuadro en awakeFromNib
.
Al crear esta pequeña subclase de NSLayoutConstraint
, ahora puedo agregar líneas de 1px en IB:
@implementation NSLayoutConstraintHairline
-(void)awakeFromNib
{
[super awakeFromNib];
if ( self.constant == 1 ) self.constant = 1/[UIScreen mainScreen].scale;
}
@end
Cualquier restricción con un valor de 1 se puede establecer en la clase NSLayoutConstraintHairline
para hacer que la constante sea efectivamente 1px en lugar de 1pt.
Si alguna vez decide cambiar la constante a otro valor, funcionará como cualquier otra restricción.
Basado en la respuesta de @ Nevs12 y sus comentarios, creo que tiene más sentido usar tal cosa:
extension NSLayoutConstraint {
@IBInspectable var usePixels: Bool {
get {
return false // default Value
}
set {
if newValue {
constant = constant / UIScreen.mainScreen().scale
}
}
}
}
Con xCode 6 y la introducción de palabras clave @IBInspectable
y @IBDesignable
, definitivamente es posible y bastante simple. No hay necesidad de subclase / salida de nada.
Puede hacer una extensión (categoría) para NSLayoutConstraint con el siguiente código (swift):
extension NSLayoutConstraint {
@IBInspectable var preciseConstant: Int {
get {
return Int(constant * UIScreen.mainScreen().scale)
}
set {
constant = CGFloat(newValue) / UIScreen.mainScreen().scale
}
}
}
Luego puede elegir la restricción necesaria en su IB.
Ve a sus propiedades y establece el valor.
En el caso anterior, mostrará una vista con una altura de 1 px en dispositivos 1x, 2x y 3x.
En Swift:
@IBOutlet var hairlineConstraint: NSLayoutConstraint! {
didSet {
hairlineConstraint.constant = 1 / UIScreen.mainScreen().scale
}
}
En caso de que alguien más venga aquí queriendo saber cómo se puede hacer programáticamente, heres cómo lo haces:
Constructor de interfaz
Establezca una restricción de altura en IB a la vista deseada y establezca la constante en 1.
Luego deberá presionar CTRL + Arrastrar desde la restricción hasta su vista personalizada o ViewController.
Siempre que el Xib esté cargado, ya sea en awakeFromNib
o viewDidLoad
, establecerá la constante de la restricción en la escala de la pantalla:
Rápido
onePixelViewHeightConstraint.constant = 1/UIScreen.main.scale//enforces it to be a true 1 pixel line
C objetivo
self.onePixelViewHeightConstraint.constant = 1.f/[UIScreen mainScreen].scale;//enforces it to be a true 1 pixel line
Disfrutar
Parece que no es posible, uno debe hacerlo mediante programación o crear una vista personalizada.
Puedes hacerlo en un archivo .xib. Simplemente edítelo como texto y establezca constant = "0.5" en vez de "1" en la restricción de altura de su vista
<constraints>
<constraint firstAttribute="height" constant="0.5" id="xUN-dm-ggj"/>
</constraints>
NSLayoutConstraint
subclase NSLayoutConstraint
:
class HairlineConstraint: NSLayoutConstraint {
override func awakeFromNib() {
super.awakeFromNib()
self.constant = 1.0 / UIScreen.main.scale
}
}
Luego simplemente cree su vista en el constructor de interfaz, agregue la restricción de altura
y establece su clase a HairlineConstraint
.
Hecho.
EDITAR: Esta respuesta fue para dispositivos @ 2x solamente. En ese momento @ 3x aún no estaba en el mercado!
Hoy en día, la respuesta de @mdvs
parece ser la más limpia.
Hacer una línea de 1px en IB es difícil incluso para dispositivos con retina solamente. Finalmente lo logré utilizando los User Defined Runtime Attributes
el User Defined Runtime Attributes
.
Aquí hay una captura de pantalla para establecer la Restricción de altura a 0.5 px (que es 1px en dispositivos Retina).