Nicolas Charvoz Nicolas Charvoz - 5 months ago 20
iOS Question

Line before and after text in UILabel

I would like to achieve the same result as this :

enter image description here

I already saw this : Draw line in UILabel before and after text , but I would like to know if there's a way to do this with only one UILabel ?

Answer

This is custom view as you requested

import UIKit

class CustomizedUILabel: UIView
{
    let label = UILabel()
    var lineInsideOffset: CGFloat = 20
    var lineOutsideOffset: CGFloat = 4
    var lineHeight: CGFloat = 1
    var lineColor = UIColor.grayColor()

//MARK: - init
    override init(frame: CGRect)
    {
        super.init(frame: frame)
        initLabel()
    }
    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)
        initLabel()
    }
    convenience init() {self.init(frame: CGRect.zero)}
    func initLabel()
    {
        label.textAlignment = .Center

        label.translatesAutoresizingMaskIntoConstraints = false
        let top = NSLayoutConstraint(item: self, attribute: .Top, relatedBy: .Equal, toItem: label, attribute: .Top, multiplier: 1, constant: 0)
        let bot = NSLayoutConstraint(item: self, attribute: .Bottom, relatedBy: .Equal, toItem: label, attribute: .Bottom, multiplier: 1, constant: 0)
        let lead = NSLayoutConstraint(item: self, attribute: .Leading, relatedBy: .LessThanOrEqual, toItem: label, attribute: .Leading, multiplier: 1, constant: 0)
        let trail = NSLayoutConstraint(item: self, attribute: .Trailing, relatedBy: .GreaterThanOrEqual, toItem: label, attribute: .Trailing, multiplier: 1, constant: 0)
        let centerX = NSLayoutConstraint(item: self, attribute: .CenterX, relatedBy: .Equal, toItem: label, attribute: .CenterX, multiplier: 1, constant: 0)

        addSubview(label)
        addConstraints([top, bot, lead, trail, centerX])

        //... if the opaque property of your view is set to YES, your drawRect: method must totally fill the specified rectangle with opaque content.
        //http://stackoverflow.com/questions/11318987/black-background-when-overriding-drawrect-in-uiscrollview
        opaque = false
    }

//MARK: - drawing
    override func drawRect(rect: CGRect)
    {
        let lineWidth = label.frame.minX - rect.minX - lineInsideOffset - lineOutsideOffset
        if lineWidth <= 0 {return}

        let lineLeft = UIBezierPath(rect: CGRectMake(rect.minX + lineOutsideOffset, rect.midY, lineWidth, 1))
        let lineRight = UIBezierPath(rect: CGRectMake(label.frame.maxX + lineInsideOffset, rect.midY, lineWidth, 1))

        lineLeft.lineWidth = lineHeight
        lineColor.set()
        lineLeft.stroke()

        lineRight.lineWidth = lineHeight
        lineColor.set()
        lineRight.stroke()
    }
}

Usage in code: in usual case you should provide top, leading and trailing/width constraints and let CustomizedUILabel to determine height by its internal UILabel. Lets show our label in debug mode in some view controller's viewDidLoad method:

override func viewDidLoad()
{
    super.viewDidLoad()

    let customizedLabel = CustomizedUILabel()
    customizedLabel.label.text = "RATE YOUR RIDE"
    customizedLabel.label.textColor = UIColor.grayColor()
    customizedLabel.label.font = customizedLabel.label.font.fontWithSize(25)
    customizedLabel.backgroundColor = UIColor.redColor()
    view.addSubview(customizedLabel)

    customizedLabel.translatesAutoresizingMaskIntoConstraints = false
    let top = NSLayoutConstraint(item: view, attribute: .Top, relatedBy: .Equal, toItem: customizedLabel, attribute: .Top, multiplier: 1, constant: -100)
    let trail = NSLayoutConstraint(item: view, attribute: .Trailing, relatedBy: .Equal, toItem: customizedLabel, attribute: .Trailing, multiplier: 1, constant: 0)
    let lead = NSLayoutConstraint(item: view, attribute: .Leading, relatedBy: .Equal, toItem: customizedLabel, attribute: .Leading, multiplier: 1, constant: 0)
    view.addConstraints([top, trail, lead])
}

Usage in xib/storyboard: as soon as you implemented init with coder initializer you can use this view in xib/storyboard. You need add UIView element to your superview, assign Class for this element to CustomizedUILabel, perform constraints and make outlet. Then you can use it with pretty same way:

@IBOutlet weak var customizedLabel: CustomizedUILabel!

override func viewDidLoad()
{
    super.viewDidLoad()

    customizedLabel.label.text = "RATE YOUR RIDE"
    customizedLabel.label.textColor = UIColor.grayColor()
    customizedLabel.label.font = customizedLabel.label.font.fontWithSize(25)
    customizedLabel.backgroundColor = UIColor.redColor()
}

enter image description here