iOS
iOS

Reputation: 3626

UITextField - Rounded corner issue

I bring the issue forward which I face. I am creating a UITextField programmatically as below.

UItextField *mobileNumberField = [[UITextField alloc] initWithFrame:CGRectMake(10, 195, 300, 41)];
mobileNumberField.delegate = self;
mobileNumberField.borderStyle = UITextBorderStyleRoundedRect;
[mobileNumberField.layer setCornerRadius:14.0f];
mobileNumberField.placeholder = @"Mobile Number";
[self.paymentsHomeView addSubview:mobileNumberField];

The output is the attached image.

enter image description here

I dont know why is it breaking at the corners. Help me to fix my text field like the image attached below.

enter image description here

Upvotes: 27

Views: 35659

Answers (9)

Paras Joshi
Paras Joshi

Reputation: 20551

Just remove this line...

mobileNumberField.borderStyle = UITextBorderStyleRoundedRect;

and add this code also..

    [mobileNumberField setBackgroundColor:[UIColor whiteColor]];
    [mobileNumberField.layer setBorderColor:[UIColor grayColor].CGColor];
    [mobileNumberField.layer setBorderWidth:1.0];

Upvotes: 30

Chandan Jee
Chandan Jee

Reputation: 5920

All above answer is good , but here I am adding the code through @IBDesignable.

enter image description here

@IBDesignable class DesignableUITextField: UITextField {

// Provides left padding for images
override func leftViewRect(forBounds bounds: CGRect) -> CGRect {
    var textRect = super.leftViewRect(forBounds: bounds)
    textRect.origin.x += leftPadding
    return textRect
}

// Provides right padding for images
override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
    var textRect = super.rightViewRect(forBounds: bounds)
    textRect.origin.x -= rightPadding
    return textRect
}

@IBInspectable var leftImage: UIImage? {
    didSet {
        updateView()
    }
}

@IBInspectable var rightImage: UIImage? {
    didSet {
        updateRightView()
    }
}

@IBInspectable var leftPadding: CGFloat = 0
@IBInspectable var rightPadding: CGFloat = 0
@IBInspectable var gapPadding: CGFloat = 0
@IBInspectable var color: UIColor = UIColor.lightGray {
    didSet {
        updateView()
    }
}
@IBInspectable var cornerRadius: CGFloat = 0
@IBInspectable var borderColor: UIColor? = .lightGray

override func draw(_ rect: CGRect) {
    layer.cornerRadius = cornerRadius
    layer.masksToBounds = true
    layer.borderWidth = 1
    layer.borderColor = borderColor?.cgColor
    
}    

//@IBInspectable var roundCornersRadius: CGFloat = 0 {
  //  didSet{
     //   roundCornersRadiusTextField(radius: roundCornersRadius)
  //  }
// }


func roundCornersRadiusTextField(radius:CGFloat) {
       roundCorners(corners: [UIRectCorner.topLeft, UIRectCorner.topRight, UIRectCorner.bottomLeft, UIRectCorner.bottomRight], radius:radius)
   }

   func roundBottomCornersRadius(radius:CGFloat) {
       roundCorners(corners: [UIRectCorner.topLeft, UIRectCorner.topRight], radius:radius)
   }

func updateView() {
    if let image = leftImage {
        leftViewMode = UITextField.ViewMode.always
        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
        imageView.contentMode = .scaleAspectFit
        imageView.image = image
        // Note: In order for your image to use the tint color, you have to select the image in the Assets.xcassets and change the "Render As" property to "Template Image".
        imageView.tintColor = color
        leftView = imageView
    } else {
        leftViewMode = UITextField.ViewMode.never
        leftView = nil
    }
    
    // Placeholder text color
    attributedPlaceholder = NSAttributedString(string: placeholder != nil ?  placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor: color])
}


func updateRightView() {
    if let image = rightImage {
        rightViewMode = UITextField.ViewMode.always
        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
        imageView.contentMode = .scaleAspectFit
        imageView.image = image
        // Note: In order for your image to use the tint color, you have to select the image in the Assets.xcassets and change the "Render As" property to "Template Image".
        imageView.tintColor = color
        rightView = imageView
    } else {
        rightViewMode = UITextField.ViewMode.never
        rightView = nil
    }
    
    // Placeholder text color
    attributedPlaceholder = NSAttributedString(string: placeholder != nil ?  placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor: color])
}

func roundCorners(corners:UIRectCorner, radius:CGFloat) {
        let bounds = self.bounds
        
        let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        
        let maskLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = maskPath.cgPath
        
        self.layer.mask = maskLayer
        
        let frameLayer = CAShapeLayer()
        frameLayer.frame = bounds
        frameLayer.path = maskPath.cgPath
        frameLayer.strokeColor = UIColor.darkGray.cgColor
        frameLayer.fillColor = UIColor.init(red: 247, green: 247, blue: 247, alpha: 0).cgColor
        
        self.layer.addSublayer(frameLayer)
    }

private var textPadding: UIEdgeInsets {
    let p: CGFloat = leftPadding + gapPadding + (leftView?.frame.width ?? 0)
    return UIEdgeInsets(top: 0, left: p, bottom: 0, right: 5)
}
override open func textRect(forBounds bounds: CGRect) -> CGRect {
    return bounds.inset(by: textPadding)
}

override open func placeholderRect(forBounds bounds: CGRect) -> CGRect {
    return bounds.inset(by: textPadding)
}

override open func editingRect(forBounds bounds: CGRect) -> CGRect {
    return bounds.inset(by: textPadding)
}}

Upvotes: 0

Alok C
Alok C

Reputation: 2857

The following code has given me the following result in Swift 5, XCode 11.4.
Definitely more bells and whistles can be added. I think this good MVP

    naviTextField = UITextField.init(frame: CGRect(x: 0, y: 0, width: (self.navigationController?.navigationBar.frame.size.width)!, height: 21))
    self.navigationItem.titleView = naviTextField
    naviTextField.becomeFirstResponder()
    naviTextField.placeholder = "Type target name here"
    naviTextField.borderStyle = .roundedRect
    naviTextField.layer.cornerRadius = 5.0
    naviTextField.textAlignment = .center

result

Upvotes: 2

cnu
cnu

Reputation: 453

swift solution:

textField.layer.borderWidth = anyWidth
textField.layer.borderColor = anyColor
textField.layer.cornerRadius = textField.frame.size.height/2
textField.clipsToBounds = true

Upvotes: 0

Miti
Miti

Reputation: 119

textField.layer.cornerRadius=textfield.frame.size.height/2;

textField.clipsToBounds=YES;

Upvotes: 8

Prasad09
Prasad09

Reputation: 11

Swift 3 solution:

I have written separate function to set border and corner radius to any layer in swift, you have to just pass the layer of any view, border width, corner radius and border color to the following function

` func setBorderAndCornerRadius(layer: CALayer, width: CGFloat, radius: CGFloat,color : UIColor ) {
        layer.borderColor = color.cgColor
        layer.borderWidth = width
        layer.cornerRadius = radius
        layer.masksToBounds = true
    }

`

Upvotes: 0

oyalhi
oyalhi

Reputation: 3994

The reason the corners are cut is because there is an enclosing view to the text field. When you set the corner radius, applies to THAT view and thus the corners of the inside text field seem to be cut - in reality they have not even changed.

The solution is to put the UITextField inside UIView, set textfield borderstyle to none. Then apply the border and corner radius specification to the uiview. Note the borderColor, which is very close, if not the same, to the UITextField borderColor.

As of writing, tested and works in Xcode 7.3.1, Swift 2.2, iOS 8 and 9.

Swift:

textField.borderStyle = UITextBorderStyle.None
textBorderView.layer.cornerRadius = 5
textBorderView.layer.borderWidth = 1
textBorderView.layer.borderColor = UIColor.lightGrayColor().colorWithAlphaComponent(0.2).CGColor

Upvotes: 6

junaidsidhu
junaidsidhu

Reputation: 3580

Here is the solution of your problem

UITextField * txtField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 200, 50)];

[txtField setBorderStyle:UITextBorderStyleNone];

[txtField.layer setMasksToBounds:YES];
[txtField.layer setCornerRadius:10.0f];
[txtField.layer setBorderColor:[[UIColor lightGrayColor]CGColor]];
[txtField.layer setBorderWidth:1];
[txtField setTextAlignment:UITextAlignmentCenter];
[txtField setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter];
[self.view addSubview:txtField];

Upvotes: 1

Paramasivan Samuttiram
Paramasivan Samuttiram

Reputation: 3738

Update your like below.

    UITextField *mobileNumberField = [[UITextField alloc] initWithFrame:CGRectMake(10, 195, 300, 41)];
    mobileNumberField.delegate = self;
    mobileNumberField.layer.borderWidth = 1.0f;
    mobileNumberField.layer.borderColor = [UIColor lightGrayColor].CGColor;
    mobileNumberField.
//    mobileNumberField.borderStyle = UITextBorderStyleRoundedRect;
    [mobileNumberField.layer setCornerRadius:14.0f];
    mobileNumberField.placeholder = @"Mobile Number";
    [self.paymentsHomeView addSubview:mobileNumberField];

Upvotes: 11

Related Questions