如何使用Swift 4从左到右设置带有圆角的渐变的UITextField边框

时间:2018-07-13 12:52:50

标签: ios swift uitextfield cagradientlayer

我正在尝试实现一个UITextField活动,该活动具有从左到右的圆形渐变边界,如以下示例所示:-

enter image description here

要求: 在这里,我有2个文本字段。在加载视图中,控制器“ Email”将使用渐变边框激活。当用户退出“电子邮件”字段时,边框将变为白色;如果再次单击“电子邮件”文本字段,则边框将变为渐变。

我尝试了以下代码,但无法正常工作:-

class CustomTextField: UITextField {

    var gradient:CAGradientLayer! = nil

    func canBecomeFirstResponder() -> Bool {
        return true
    }

    override func becomeFirstResponder() -> Bool {

        let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: [.topLeft, .bottomLeft, .topRight, .bottomRight], cornerRadii: CGSize(width: frame.size.height / 2, height: frame.size.height / 2))

        gradient = CAGradientLayer()
        gradient.frame =  CGRect(origin: CGPoint.zero, size: frame.size)
        gradient.colors = [UIColor.green.cgColor, UIColor.red.cgColor]

        let shape = CAShapeLayer()
        shape.lineWidth = 10
        shape.path = path.cgPath
        shape.strokeColor = UIColor.black.cgColor
        shape.fillColor = UIColor.clear.cgColor
        gradient.mask = shape

        layer.addSublayer(gradient)

        super.becomeFirstResponder()
        return true
    }

    override func resignFirstResponder() -> Bool {
        gradient.colors = [UIColor.white.cgColor]
        super.resignFirstResponder()
        return true
    }
}

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var txtEmail: CustomTextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.


    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        txtEmail.resignFirstResponder()
        return true
    }
}

有三个我无法解决的问题:- 1-我已经设置了lineWidth 10,但是它在角落和水平/垂直方向仅显示了5的宽度10。 2-我想显示从左到右而不是从上到下的渐变。 3-当我辞职时,没有设置白色边框

enter image description here

请帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

该线在路径的中央描边,因此10像素的宽度表示每侧5像素。您的形状被剪裁在侧面,因此您需要插入路径。

问题1

let lineWidth: CGFloat = 10   
let rect = bounds.inset.bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)

let path = UIBezierPath(roundedRect: rect, cornerRadius: frame.size.height / 2)
shape.lineWidth = lineWidth

或者,如果您想在路径的中央划过线,则需要设置CustomTextField的{​​{1}}

问题2

要更改渐变角度,请使用clipsToBounds = falsestartPoint

endPoint

问题3

可能尝试

gradient.startPoint = CGPoint(x: 0, y: 0.5)
gradient.endPoint = CGPoint(x: 1, y: 0.5)

答案 1 :(得分:0)

首先选择“在XCode的元素检查器中没有边框”

然后使用下面的代码

    let lineWidth: CGFloat = 1
    let rect = myTextField.bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)

    let path = UIBezierPath(roundedRect: rect, cornerRadius: myTextField.frame.size.height / 2)

    let gradient = CAGradientLayer()
    gradient.frame =  CGRect(origin: CGPoint.zero, size: myTextField.frame.size)
    gradient.colors = [UIColor.green.cgColor, UIColor.red.cgColor, UIColor.green.cgColor]
    gradient.startPoint = CGPoint(x: 0, y: 0.5)
    gradient.endPoint = CGPoint(x: 1, y: 0.5)

    let shape = CAShapeLayer()
    shape.lineWidth = lineWidth

    shape.path = path.cgPath
    shape.strokeColor = UIColor.black.cgColor
    shape.fillColor = UIColor.clear.cgColor
    gradient.mask = shape

    myTextField.layer.addSublayer(gradient)

P.S。此答案完全受@Ashley的答案启发。