katit
katit

Reputation: 17915

UITextField set border color using storyboard

I'd like to set border color using storyboard if possible. I've seen answer here: UITextField border color

And I followed answer in storyboard:

enter image description here

All properties set, but TextField doesn't show border. Any suggestions?

Upvotes: 20

Views: 31248

Answers (6)

Adition to markus, put the full code:

import UIKit //IMPORTANT
@IBDesignable
class BorderTextField: UITextField {
 @IBInspectable var borderColor: UIColor? {
    didSet {
        layer.borderColor = borderColor?.cgColor
    }
 }
 @IBInspectable var borderWidth: CGFloat = 0 {
    didSet {
        layer.borderWidth = borderWidth
    }
 }
}

Upvotes: 3

Markus
Markus

Reputation: 686

Well as Bogdan pointed out, you could very well do that with simple subclassing and just a few bits of code. After that everything will be editable in Storyboards.

  1. Subclass UITextField
  2. Create two properties, one for border width and one for border color
  3. Make those variables IBInspectable and entire class IBDesignable
  4. You'll be able to change color and width of border and see the change in real time.

Code for illustration (Swift 3.1):

@IBDesignable
class FormTextField: UITextField {

    @IBInspectable var borderColor: UIColor? {
        didSet {
            layer.borderColor = borderColor?.cgColor
        }
    }

    @IBInspectable var borderWidth: CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
}

Edit: You'll see this in your Attributes Inspector

Attributes Inspector

Upvotes: 18

Rameswar Prasad
Rameswar Prasad

Reputation: 1331

As Bogdan pointed out it's true that you can't find the layer.borderColor property in storyboard as it's a run time thing.

However still you can set the borderColor without using IB_DESIGNABLE, on any view(or UIView Subclass) with a little bit of coding.

Below are the steps how to achieve it,

  1. Create a category on CALayer class. Declare a property of type UIColor with a suitable name, I'll name it as borderUIColor .
  2. Write the setter and getter for this property.
  3. In the 'Setter' method just set the "borderColor" property of layer to the new colors CGColor value.
  4. In the 'Getter' method return UIColor with layer's borderColor.

P.S: Remember, Categories can't have stored properties. 'borderUIColor' is used as a calculated property, just as a reference to achieve what we're focusing on.

Please have a look at the below code sample;

Objective C:

Interface File:

#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>

@interface CALayer (BorderProperties)

// This assigns a CGColor to borderColor.
@property (nonatomic, assign) UIColor* borderUIColor;

@end

Implementation File:

#import "CALayer+BorderProperties.h"

@implementation CALayer (BorderProperties)

- (void)setBorderUIColor:(UIColor *)color {
    self.borderColor = color.CGColor;
}

- (UIColor *)borderUIColor {
    return [UIColor colorWithCGColor:self.borderColor];
}

@end

Swift 3.1:

extension CALayer {
    var borderUIColor: UIColor {
        set {
            self.borderColor = newValue.cgColor
        }

        get {
            return UIColor(cgColor: self.borderColor!)
        }
    }
}

And finally go to your storyboard/XIB, follow the remaining steps;

  1. Click on the View object for which you want to set border Color.
  2. Click on "Identity Inspector"(3rd from Left) in "Utility"(Right side of the screen) panel.
  3. Under "User Defined Runtime Attributes", click on the "+" button to add a key path.
  4. Set the type of the key path to "Color".
  5. Enter the value for key path as "layer.borderUIColor". [Remember this should be the variable name you declared in category, not borderColor here it's borderUIColor].
  6. Finally chose whatever color you want.

Edit: You've to set layer.borderWidth property value to at least 1 to see the border color.

Build and Run. Happy Coding. :)

Upvotes: 7

FranMowinckel
FranMowinckel

Reputation: 4343

This is a variant over @rameswar answer which I think it's correct. Since we're applying a UIColor, I think it's preferable to write an extension for the UITextField instead (UI things together):

extension UITextField {

  var borderColor : UIColor? {
    get {
      if let cgcolor = layer.borderColor {
        return UIColor(CGColor: cgcolor)
      } else {
        return nil
      }
    }
    set {
      layer.borderColor = newValue?.CGColor

      // width must be at least 1.0
      if layer.borderWidth < 1.0 {
        layer.borderWidth = 1.0
      }
    }
  }
}

The runtime property would be then borderColor (so you don't need to type layer. and I think it's a bit cleaner than borderUIColor).

The borderColor of CALayer is optional so it's this property. It gets black when set to nil

And finally, the layer.borderWidth it's set to a minimum 1.0 because the color it's not set otherwise.

Upvotes: 1

Bogdan Raducan
Bogdan Raducan

Reputation: 177

It doesn't show any border because of the layer.borderColor property. It's of type CGColor and Runtime attributes doesn't yet support that by default so, setting just one attribute wrong, disables the other ones as well.

To do it from the storyboard but also involving some code and subclassing, you can use this method:

Subclass UITextField and make an IB_DESIGNABLE UIColor property, that you'll then transform into CGColor and apply it to self.layer.borderColor.

Upvotes: 0

Gismay
Gismay

Reputation: 814

I'm not sure you can change the border colour of a UITextfield in storyboard. You can change it programmatically with something along the lines of;

UITextField *myTextField = (UITextField *)[self.view viewWithTag:1];
myTextField.borderStyle = UITextBorderStyleLine;
myTextField.layer.borderWidth = 2;
myTextField.layer.borderColor = [[UIColor redColor] CGColor];

Hope this helps.

Upvotes: 3

Related Questions