[iOS/Swift] 텍스트필드에 그라데이션 테두리를 적용해 보자

Nakyung Lee·2023년 9월 21일
0

iOS

목록 보기
12/14

오늘 만들 것은 바로 아래와 같은 그라데이션 테두리 텍스트필드이다!
그럼 지금부터 시작 😎

1️⃣ UITextField Delegate 위임

override func viewDidLoad() {
        super.viewDidLoad()
        
        emailField.delegate = self
        passField.delegate = self
        
        ... (생략)
 }

먼저 UITextField의 델리게이트를 위임해 준다

2️⃣ extension 작성

extension UITextField {
    private func applyGradientBorder(colors: [CGColor]) {
        let lineWidth: CGFloat = 2
        let rect = self.bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)
        
        let path = UIBezierPath(roundedRect: rect, cornerRadius: 14)
        
        let gradient = CAGradientLayer()
        gradient.frame =  CGRect(origin: CGPoint.zero, size: self.frame.size)
        gradient.colors = colors
        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
        
        self.layer.addSublayer(gradient)
    }
    
    private func applyOriginalBorder(color: UIColor) {
        let rect = self.bounds.insetBy(dx: 1, dy: 1)
        
        let path = UIBezierPath(roundedRect: rect, cornerRadius: 14)
        
        let shape = CAShapeLayer()
        shape.lineWidth = 2
        
        shape.path = path.cgPath
        shape.strokeColor = UIColor.Text05?.cgColor
        shape.fillColor = UIColor.clear.cgColor
        
        self.layer.addSublayer(shape)
    }
    
    func setGradientBorderColor(colors: [CGColor]) {
        self.layer.sublayers?.removeAll { $0 is CAShapeLayer }
        applyGradientBorder(colors: colors)
    }
    
    func setOriginalBorderColor(color: UIColor) {
        self.layer.sublayers?.removeAll { $0 is CAGradientLayer }
        applyOriginalBorder(color: color)
    }
}

그라데이션 테두리 설정, 기본 테두리 설정 두 개의 함수를 작성해 주었다. 기본 테두리는 그냥 단색이어서 CAShapeLayr만 사용해 주었다.

cornerRadius 값도 지정해 주고, 테두리를 적용할 때는 layer를 제거해 주고 그 위에 다시 레이어를 올리는 방식인데 이때 특정 형식을 지정해서 해당 형식의 레이어만 지워지도록 구현했다!

3️⃣ 기본 스타일 지정

override func viewDidLoad() {
        super.viewDidLoad()
        
        emailField.delegate = self
        passField.delegate = self
        
        // 텍스트필드 스타일 설정
        emailField.borderStyle = .none
        emailField.setOriginalBorderColor(color: UIColor.Text05!)
        
        passField.borderStyle = .none
        passField.setOriginalBorderColor(color: UIColor.Text05!)
        
        // 텍스트필드 왼쪽 여백 만들기
        let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: 13, height: emailField.frame.height))
        
        emailField.leftView = paddingView
        emailField.leftViewMode = .always
            
        passField.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 13, height: passField.frame.height))
        passField.leftViewMode = .always
}

맨 처음에는 기본 테두리가 적용되도록 함수를 사용해 주고, borderStyle은 none으로 지정해 준다. layer를 위에 올리는 것이기 때문에 none으로 해 주지 않으면 기본 테두리가 보이기 때문 😏

4️⃣ 입력 시 그라데이션 테두리 적용

// 입력 시 텍스트필드 테두리 색상 변경
    func textFieldDidBeginEditing(_ textField: UITextField) {
        if textField == emailField {
            emailField.setGradientBorderColor(colors: [UIColor(red: 0.393, green: 0.538, blue: 0.983, alpha: 1).cgColor, UIColor(red: 0.557, green: 0.667, blue: 1, alpha: 1).cgColor])
        } else {
            passField.setGradientBorderColor(colors: [UIColor(red: 0.393, green: 0.538, blue: 0.983, alpha: 1).cgColor, UIColor(red: 0.557, green: 0.667, blue: 1, alpha: 1).cgColor])
        }
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        if textField == emailField {
            emailField.setOriginalBorderColor(color: UIColor.Text05!)
        } else {
            passField.setOriginalBorderColor(color: UIColor.Text05!)
        }
    }

if문을 써서 어떤 텍스트필드인지 구분지어 적용해 준다

🥳 완성!

짜잔 요렇게 하면 텍스트 필드를 선택했을 때만 테두리 색상이 변경된다. 야호!
profile
앱 개발자를 꿈꾸는 ✨

0개의 댓글