How do I create a 1px line in Interface Builder?

不问归期 提交于 2019-11-27 17:24:09

Just in case someone else comes here wanting to know how it can be done programmatically, heres how you do it:

Interface Builder

Make a height constraint in IB to the desired view and set the constant to 1.

Then you will need to CTRL+Drag from the constraint into your custom view or ViewController.

Whenever the Xib is loaded, be it in awakeFromNib or viewDidLoad, you are going to set the constant of the constraint to the scale of the display:

Swift

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

Objective-C

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

Enjoy

Marius Kažemėkaitis

I created NSLayoutConstraint subclass:

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

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

Then simply create your view in interface builder, add height constraint

and set its class to HairlineConstraint.

Done.

By creating this tiny subclass of NSLayoutConstraint I'm now able to add 1px lines in IB:

@implementation NSLayoutConstraintHairline

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

@end

Any constraint with a value of 1 can be set to class NSLayoutConstraintHairline to make the constant effectively 1px instead of 1pt.

If you ever decide to change the constant to another value, it will just work as any other constraint.

With xCode 6 and introduction of @IBInspectable and @IBDesignable keywords it is definitely possible and rather simple. No need to subclass/outlet anything.

You can do an extension (category) for NSLayoutConstraint with following code (swift):

extension NSLayoutConstraint {

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

Then you can choose needed constraint in your IB.

Go to it's properties and set the value.

In above case it will render a view with 1 px height on 1x, 2x and 3x devices.

In Swift:

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

EDIT: This answer was for @2x only devices. At that time @3x was not yet on the market!

Nowadays, @mdvs's answer seems to be the cleanest.


Making 1px line in IB is hard even for retina-only devices. Finally I've achieved it using the User Defined Runtime Attributes.

Here's a screenshot for setting the Height Constraint to 0.5 px (which is 1px on retina devices).

Based on @Nevs12 's answer and it's comments, I think it makes more sense to use such thing:

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

Seems that it is not possible, one must do it programmatically or build a custom view.

You can do it in .xib file. Just edit it as text and set constant="0.5" instead of "1" in your view height constraint

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

In Interface Builder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!