UITextField Only Top And Bottom Border

41,816

Solution 1

One approach I have found works good is using layers. Here's a snippet:

CALayer *bottomBorder = [CALayer layer];
bottomBorder.frame = CGRectMake(0.0f, self.frame.size.height - 1, self.frame.size.width, 1.0f);
bottomBorder.backgroundColor = [UIColor blackColor].CGColor;
[myTextField.layer addSublayer:bottomBorder];

Hope this helps someone.

Solution 2

@user3075378's great & simple example in Swift

var bottomBorder = CALayer()
bottomBorder.frame = CGRectMake(0.0, textField.frame.size.height - 1, textField.frame.size.width, 1.0);
bottomBorder.backgroundColor = UIColor.blackColor().CGColor
textField.layer.addSublayer(bottomBorder)

Solution 3

@Sebyddd why stop there? (;

EDIT: There is an issue with lines being drawn before auto layout sets the right frame for the view, I edited my answer with a fix: it basically involves calling drawLines() in layoutSubviews():

class FramedTextField: UITextField {

    @IBInspectable var linesWidth: CGFloat = 1.0 { didSet{ drawLines() } }

    @IBInspectable var linesColor: UIColor = UIColor.blackColor() { didSet{ drawLines() } }

    @IBInspectable var leftLine: Bool = false { didSet{ drawLines() } }
    @IBInspectable var rightLine: Bool = false { didSet{ drawLines() } }
    @IBInspectable var bottomLine: Bool = false { didSet{ drawLines() } }
    @IBInspectable var topLine: Bool = false { didSet{ drawLines() } }



    func drawLines() {

        if bottomLine {
            add(CGRectMake(0.0, frame.size.height - linesWidth, frame.size.width, linesWidth))
        }

        if topLine {
            add(CGRectMake(0.0, 0.0, frame.size.width, linesWidth))
        }

        if rightLine {
            add(CGRectMake(frame.size.width - linesWidth, 0.0, linesWidth, frame.size.height))
        }

        if leftLine {
            add(CGRectMake(0.0, 0.0, linesWidth, frame.size.height))
        }

    }

    typealias Line = CGRect
    private func add(line: Line) {
        let border = CALayer()
        border.frame = line
        border.backgroundColor = linesColor.CGColor
        layer.addSublayer(border)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        drawLines()
    }

}

Solution 4

you can create one image that with top and bottom border and set it to the background of your UITextField :

yourTextField.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"yourBorderedImageName"]];

Solution 5

You can also add views to the top and bottom to use as borders.

// Top border
UIView *topBorder = [[UIView alloc]
    initWithFrame:CGRectMake(0,
                             0,
                             textfield.frame.size.width,
                             4.0f)];
topBorder.backgroundColor = [UIColor colorWithRed:160/255.0f
                                            green:160/255.0f
                                             blue:160/255.0f
                                            alpha:1.0f];
[textfield addSubview:topBorder];

// Bottom border
UIView *bottomBorder = [[UIView alloc]
    initWithFrame:CGRectMake(0,
                             textfield.frame.origin.y +
                                 textfield.frame.size.height - 4.0f,
                             textfield.frame.size.width,
                             4.0f)];
bottomBorder.backgroundColor = [UIColor colorWithRed:160/255.0f
                                               green:160/255.0f
                                                blue:160/255.0f
                                               alpha:1.0f];
[textfield addSubview:bottomBorder];
Share:
41,816

Related videos on Youtube

GangstaGraham
Author by

GangstaGraham

Updated on July 09, 2022

Comments

  • GangstaGraham
    GangstaGraham almost 2 years

    I currently have a regular border. I would like to only have a top and bottom border.

    How do I accomplish this?

    Using the UITextField's layer property, I have the following code:

        self.layer.borderColor = [[UIColor colorWithRed:160/255.0f green:160/255.0f blue:160/255.0f alpha:1.0f] CGColor];
        self.layer.borderWidth = 4.0f;
    

    I have kind of got it to work by making my UITextField extra long, so that the user does not see the left and right borders, but I was just wondering if there was a better, less hackish way of doing this?

    I have checked the docs, and changing a UITextField's borderStyle does not have this option.

    From,

    An iOS First Timer

  • GangstaGraham
    GangstaGraham about 11 years
    Hmm... this seems pretty hackish too, I am surprised there is no way via border style or something simpler to do this, I will see what other people have to say, maybe they might know a better way.
  • KDeogharkar
    KDeogharkar about 11 years
    yes I had the same issue and finally I come out with this option.
  • TylerJames
    TylerJames almost 10 years
    Excellent, thanks for the idea. Just a note: since you're adding the border as a subview of the UITextField itself you probably don't want to position the border based on the textfield's origin since that refers to the coordinate space of its parent. You'd want the top border to start at (0,0) and the bottom to start at: (textfield.frame.size.height - 4.0f)
  • netwire
    netwire over 9 years
    Does this work if your UITextField's height or width changes?
  • Zorayr
    Zorayr over 9 years
    What's the performance impact for drawing the line as opposed to adding a subview?
  • Gerard
    Gerard over 9 years
    @Zorayr A layer seems like a pretty simple object compared to a UIView so, at a educated guess, I reckon layers would be much more performant.
  • Yarlik
    Yarlik over 9 years
    Just a useful remark. If this code is added to parent view controller, the lines won't change their lengths when device changes orientation. To handle this (and avoid subclassing), I rendered CAShapeLayer to image, and used that image as a background for textfield. Code to render image: UIGraphicsBeginImageContextWithOptions(textField.bounds.size‌​, textField.opaque, 0.0); [line renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [textField setBackground:image];
  • melissa.mcmurtrie
    melissa.mcmurtrie about 9 years
    @Dean You can slice the image in the asset catalog to create repeating portions so the image won't stretch. There's a button in the lower right corner of the image view that will show you the slices or you can add them in the attributes inspector.
  • bobbaluba
    bobbaluba almost 9 years
    @kareem why? The question is tagged objective-c and it's also used in the question.
  • Ricardo Alves
    Ricardo Alves over 8 years
    I'm new to objective c and I'm having difficulties creating a class, can you try to explain how I can do it? Thanks in advance
  • Aviel Gross
    Aviel Gross over 8 years
    @RicardoAlves in Xcode, on the left in Project Navigator (where all the files are) right click > New File > under iOS choose Source > Cocoa Touch Class> hit Next to enter the class name, parent etc.
  • Pedro Góes
    Pedro Góes about 8 years
    That should be the accepted answer. Without auto layout support, it's a prototype.
  • Peterdk
    Peterdk about 8 years
    This doesn't work on iOS 7. It displays a extra bottom border, but keeps the side and top lines.
  • Emptyless
    Emptyless almost 8 years
    Because there may be more people with the same problem that are using Swift instead of Objective-C. I am for example happy that he posted it in Swift
  • John
    John about 7 years
    @Peterdk, It will work, if you past above code in viewDidAppears(animated).