이메일이랑 비밀번호를 입력 받는 화면을 만들어 보자. 그리고 이메일과 비밀번호 형식이 맞는지 확인해서 에러까지 출력해보자
화면을 저렇게 만드는건 라벨 몇 개, 텍스트 필드 두개, 버튼 하나면 저렇게 완성! 이 된다.
그럼 이제 동작을 어떻게 할 것인지 생각해본다.
텍스트필드 안에 값을 입력 받는다. 근데 그 값이 어떤 값인지, 형식에 맞는 건지 어떻게 판단할것인가?
이메일, 비밀번호 형식은 어떻게 판단할 것인가?
에러 메시지가 사라졌다 지워졌다 하는 건 어떻게 하나?
addTarget
메소드를 이용하여 텍스트필드 값이 변화하는 것을 캐치해 낸다.
How do I check when a UITextField Changes? - StackOverflow
근데 이 방법은 상당히 옛날 방법인듯. 강좌가 아무래도 오래되었다 보니 그런거 같다. 조만간 완강하고 얼른 SwiftUI 강의로 넘어가야 할듯하다.
정규식을 사용하면 된다.(Regualr Expression)
정규 표현식에 관해서는 공부를 하는게 좋지만, 필수는 아니라고 한다. 따라서 구글링으로 찾을 수 있을 정도면 된다고함!
(그래도 나중에 커스터마이징하려면 공부해야지)
구글에 Swift regular expression email 이라고 치면 다 나온다.
func isValidEmail(testStr: String?) -> Bool {
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return emailTest.evaluate(with: testStr)
}
이게 이메일인지 판단하는 정규식이다.
우리는 비밀번호를 8자리 이상으로만 만들면 된다는 조건으로 할 것이기 때문에 굳이 정규식이 필요없고 우리가 알아서 코딩하면 된다.
func isValidPassword(pw: String?) -> Bool{
if let hasPassword = pw{
if hasPassword.count < 8{
return false
}
}
return true
}
이렇게 만들었다.(물론 내가 아니라 강의에서..그래도 다 이해는 할 수 있어야 한다.)
이 문제는 정말 다양한 방법이 있을 거라고 생각한다. 나는 강의를 보면서 에러 메세지의 Opacity 나 Alpha값을 건드려서 투명하게 만드는 것을 생각했었고, 강의에서는 Text Label의 높이를 아예 0으로 만들어서 사라지게 만들었다. 이 방법들 말고도 여러가지 방법이 있을 것이다.
근데 강의에서 높이를 0으로 만들면서 주의할 점이 하나 있었는데, object.heightanchor.constraint(equalToConstant: 0)
을 쓰면서 함수 안에서 단순하게 계속 반복하게 되면, 이게 결국 Constraints를 계속 추가하게 되는 것이라 나중에 충돌오류가 발생하게 될 가능성이 굉장히 높다는 것이다.
그래서 강의에서는 전역 변수로 이 값을 지정해서 .setActive
를 True or False 로 바꾸는 식으로 오류를 해결했다.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var emailErrorLabel: UILabel!
@IBOutlet weak var passwordErrorLabel: UILabel!
var emailerrorheight: NSLayoutConstraint!
var passworderrorheight: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// Textfield 값이 변경되는 것을 캐치하는 게 없음.
emailTextField.addTarget(self, action: #selector(textFieldEdited), for: UIControl.Event.editingChanged)
passwordTextField.addTarget(self, action: #selector(textFieldEdited), for: .editingChanged)
emailerrorheight = emailErrorLabel.heightAnchor.constraint(equalToConstant: 0)
passworderrorheight = passwordErrorLabel.heightAnchor.constraint(equalToConstant: 0)
}
// #selector에서 @objc 가 없으면 호환이 안돼서 붙여줘야함
@objc func textFieldEdited(textField: UITextField) {
if textField == emailTextField{
if isValidEmail(testStr: textField.text)
{
emailerrorheight.isActive = true
}
else{
emailerrorheight.isActive = false
}
}
else if textField == passwordTextField{
if isValidPassword(pw: textField.text)
{
passworderrorheight.isActive = true
}
else{
passworderrorheight.isActive = false
}
}
UIView.animate(withDuration: 0.1) { // 효과 주기
self.view.layoutIfNeeded()
}
}
// 정규식
func isValidEmail(testStr: String?) -> Bool {
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return emailTest.evaluate(with: testStr)
}
func isValidPassword(pw: String?) -> Bool{
if let hasPassword = pw{
if hasPassword.count < 8{
return false
}
}
return true
}
}
뭔가 강의 막바지에 오니까 배운게 의미가 있는 거 같으면서도 얼른 SwiftUI 강의를 들어버리고 싶은.. 그래도 이제 마지막 메신저 만들기 강좌가 있으니 그거 빨리 들어야겠다!