0

I need to use a textfield to havet he user type in phone numbers so I'm using the PhoneNumberTextField from the project PhoneNumberKit.

By default it's just a borderless textfield. I modified it by adding a border with a corner radius and a UIButton added to its leftView. The problem with that is the text/placeholder is shown right up against the border.

enter image description here

enter image description here

I tried subclassing PhoneNumberTextField and adding the text inset capability like this.

@IBDesignable
class CNPhoneNumberTextField: PhoneNumberTextField {
    @IBInspectable var inset: CGFloat = 0

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: inset, dy: inset)
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: inset, dy: inset)
    }

    override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: inset, dy: inset)
    }
}

The issue here is it doesn't take the leftView into account now. The text/placeholder is partially covered by the leftView.

enter image description here

Is there any other way to fix this?

Demo project

Isuru
  • 30,617
  • 60
  • 187
  • 303

2 Answers2

2

You need to update your CNPhoneNumberTextField class like shown below where you can give leftPadding for your textField from storyboard.

Your class will look like:

import UIKit
import PhoneNumberKit

@IBDesignable
class CNPhoneNumberTextField: PhoneNumberTextField {

    @IBInspectable var leftPadding: CGFloat = 0

    override open func textRect(forBounds bounds: CGRect) -> CGRect {

        let padding = UIEdgeInsets(top: 0, left: leftPadding, bottom: 0, right: 0)
        return bounds.inset(by: padding)
    }

    override open func placeholderRect(forBounds bounds: CGRect) -> CGRect {

        let padding = UIEdgeInsets(top: 0, left: leftPadding, bottom: 0, right: 0)
        return bounds.inset(by: padding)
    }

    override open func editingRect(forBounds bounds: CGRect) -> CGRect {

        let padding = UIEdgeInsets(top: 0, left: leftPadding, bottom: 0, right: 0)
        return bounds.inset(by: padding)
    }
}

And from storyboard with Attribute inspector section you can assign left padding like:

enter image description here

And your result will be:

enter image description here

Reference from THIS answer.

EDIT:

HERE is the demo project.

Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
  • Hi, thanks for the answer. For some reason, it's still not working for me. Can you please attach the Xcode project? – Isuru Feb 25 '19 at 10:45
  • Yes sure. Will do it. – Dharmesh Kheni Feb 25 '19 at 10:46
  • I see. You increased the padding value to a bigger number so it will go past the `leftView`. I was wondering why the textRect doesn't take the `leftView`'s bounds into account. – Isuru Feb 25 '19 at 10:55
  • It's taking `leftView`'s bounds into account thats why you are getting result which you showed in you first image in your question – Dharmesh Kheni Feb 25 '19 at 11:19
0

You could probably add some padding like this:

override func textRect(forBounds bounds: CGRect) -> CGRect {
    var rect = super.textRect(forBounds: bounds)
    rect.origin.x += 10
    return rect
}
rodskagg
  • 3,827
  • 4
  • 27
  • 46