How to add only a TOP border on a UIButton?

48,230

Solution 1

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, btn.frame.size.width, 1)];
lineView.backgroundColor = [UIColor redColor];
[btn addSubview:lineView];

you can do the same for each border. Adding multiple UIViews you can add bottom and left or top and right or any border you want.

i.e. bottom & left:

UIView *bottomBorder = [[UIView alloc] initWithFrame:CGRectMake(0, btn.frame.size.height - 1.0f, btn.frame.size.width, 1)];
bottomBorder.backgroundColor = [UIColor redColor];

UIView *leftBorder = [[UIView alloc] initWithFrame:CGRectMake(1, 0, 1, btn.frame.size.height)];
leftBorder.backgroundColor = [UIColor redColor];

[btn addSubview:bottomBorder];
[btn addSubview:leftBorder];

if you don't use ARC, remember to release UIViews after adding subviews (or use autorelease).

Solution 2

Here is masgar's solution implemented in Swift:

var lineView = UIView(frame: CGRectMake(0, 0, btn.frame.size.width, 1))
lineView.backgroundColor=UIColor.redColor()
btn.addSubview(lineView)

Solution 3

In Swift add an extension for UIView class like this:

extension UIView {
    func addTopBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:0,y: 0, width:self.frame.size.width, height:width)
        self.layer.addSublayer(border)
    }

    func addRightBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x: self.frame.size.width - width,y: 0, width:width, height:self.frame.size.height)
        self.layer.addSublayer(border)
    }

    func addBottomBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:0, y:self.frame.size.height - width, width:self.frame.size.width, height:width)
        self.layer.addSublayer(border)
    }

    func addLeftBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:0, y:0, width:width, height:self.frame.size.height)
        self.layer.addSublayer(border)
    }
}

I got this extension from this link:UIView bottom border?

Then call the function like this

var innerView : UIView?
let borderWidth: CGFloat = 1.0
let borderColor : UIColor =  UIColor.redColor()
innerView!.addTopBorderWithColor(borderColor, width: borderWidth)

For adaptive layout use this one

extension UIView {

    func addTopBorder(_ color: UIColor, height: CGFloat) {
        let border = UIView()
        border.backgroundColor = color
        border.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(border)
        border.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.height,
            relatedBy: NSLayoutRelation.equal,
            toItem: nil,
            attribute: NSLayoutAttribute.height,
            multiplier: 1, constant: height))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.top,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.top,
            multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.leading,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.leading,
            multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.trailing,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.trailing,
            multiplier: 1, constant: 0))
    }

    func addBottomBorder(_ color: UIColor, height: CGFloat) {
        let border = UIView()
        border.backgroundColor = color
        border.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(border)
        border.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.height,
            relatedBy: NSLayoutRelation.equal,
            toItem: nil,
            attribute: NSLayoutAttribute.height,
            multiplier: 1, constant: height))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.bottom,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.bottom,
            multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.leading,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.leading,
            multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.trailing,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.trailing,
            multiplier: 1, constant: 0))
    }

    func addLeftBorder(_ color: UIColor, width: CGFloat) {
        let border = UIView()
        border.backgroundColor = color
        border.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(border)
        border.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.width,
            relatedBy: NSLayoutRelation.equal,
            toItem: nil,
            attribute: NSLayoutAttribute.width,
            multiplier: 1, constant: width))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.leading,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.leading,
            multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.bottom,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.bottom,
            multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.top,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.top,
            multiplier: 1, constant: 0))
    }

    func addRightBorder(_ color: UIColor, width: CGFloat) {
        let border = UIView()
        border.backgroundColor = color
        border.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(border)
        border.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.width,
            relatedBy: NSLayoutRelation.equal,
            toItem: nil,
            attribute: NSLayoutAttribute.width,
            multiplier: 1, constant: width))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.trailing,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.trailing,
            multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.bottom,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.bottom,
            multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: border,
            attribute: NSLayoutAttribute.top,
            relatedBy: NSLayoutRelation.equal,
            toItem: self,
            attribute: NSLayoutAttribute.top,
            multiplier: 1, constant: 0))
    }
}

Usage:

button!.addTopBorder(UIColor(red: 247.0/255.0, green: 147.0/255.0, blue: 29.0/255.0, alpha: 0.5), height: borderWidth)

Solution 4

Swift 4

UIButton Top Border

var lineView = UIView(frame: CGRect(x: 0, y: 0, width: button.frame.size.width, height: 2))
lineView.backgroundColor= UIColor.black
button.addSubview(lineView)

UIButton Bottom Border

var lineView = UIView(frame: CGRect(x: 0, y: button.frame.size.height, width: button.frame.size.width, height: 2))
lineView.backgroundColor= UIColor.black
button.addSubview(lineView)

Solution 5

Just draw the border yourself:

@implementation TopBorderButton
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
    CGContextFillRect(context, CGRectMake(0.0f, 0.0, self.frame.size.width, 1.0));
}
@end
Share:
48,230
Jonathan F.
Author by

Jonathan F.

Updated on July 09, 2022

Comments

  • Jonathan F.
    Jonathan F. almost 2 years

    I know how to add border to a button in iOS 7, with the following code :

    [[myButton layer] setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]];
    [[myButton layer] setBorderWidth:1];
    [[myButton layer] setCornerRadius:15];
    

    But how can I add just one border ? I want to add only the top border.

  • masgar
    masgar about 10 years
    @Chris.Jenkins it is very strange it doesn't work. It should works with any type of UIButton, from IB or programmatically. It siply add a subview with button width and 1px height. Try to check button and lineview frame by logging them: NSLog(@"btn frame: %@", NSStringFromCGRect(btn.frame));
  • Mohd Sadham
    Mohd Sadham over 7 years
    How to remove this border view on runtime? Ex: When button action is triggered i need to remove that border. Please reply. @masgar
  • Mohd Sadham
    Mohd Sadham over 7 years
    How to remove this border view on runtime? Ex: When button action is triggered i need to remove that border. Please reply.
  • peacetype
    peacetype over 7 years
    I haven't checked this myself yet but try lineView.removeFromSuperview() See this for more information, as I may have gotten it wrong: stackoverflow.com/q/28197079/4376309
  • c_sharma
    c_sharma about 7 years
    for the adaptive layout part, you need to change the constant value from 1 to 'width' parameter.
  • Kiran P Nair
    Kiran P Nair about 7 years
    @ c_sharma thank u, corrected my mistake and updated
  • masgar
    masgar almost 7 years
    you can set a tag to each view and remove view with tag from superview.
  • J. Doe
    J. Doe over 6 years
    That adaptive workaround is cool since my views can change a lot, thanks
  • Shourob Datta
    Shourob Datta over 5 years
    how can i add shadow on border ? @masgar
  • masgar
    masgar over 5 years
    there are tons of answer about shadow. The border you add is a view and you can add shadow to a view by using QuartzCore. check tis answer: stackoverflow.com/questions/805872/…
  • Kilmazing
    Kilmazing about 5 years
    I was adding the border as a UIView() and it would not show. Making it a CALayer() works. Thanks!
  • Nick N
    Nick N over 3 years
    Excellent answer. Only 1 line of code is needed by a caller along with using a consistent enum for sides. Well done.