아래와 같이 storyboard와 outlet을 설정하였다.
각각 textField는 아래와 같이 설정을 할 수 있다.
마지막 emailTextField만 아래와 같이 설정을 한다.
namefield는 10자리만 입력이 가능하게, ageField는 1~100만 입력이 가능하게, genderfield는 M or F만 입력이 가능하게, emailField는 포멧에 맞게만 입력이 가능하게 설정을 하기
import UIKit
class TextDelegateViewController: UIViewController {
@IBOutlet weak var nameField: UITextField!
@IBOutlet weak var ageField: UITextField!
@IBOutlet weak var genderField: UITextField!
@IBOutlet weak var emailField: UITextField!
// 이메일의 포멧이다!
let regex = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"
// 숫자제외 모든 문자를 set으로 생성
lazy var charSet = CharacterSet(charactersIn: "0123456789").inverted
// MF제외 모든 문자를 set으로 생성
lazy var invalidGenderCharSet = CharacterSet(charactersIn: "MF").inverted
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// 바로 편집모드로 설정한다.
nameField.becomeFirstResponder()
}
}
extension TextDelegateViewController: UITextFieldDelegate{
// return 키를 누르면 다음 textfield로 넘어가게 하기
// textfield에서 return 키가 눌러지면 해당 함수가 실행이된다.
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
switch textField {
case nameField:
ageField.becomeFirstResponder()
case ageField:
genderField.becomeFirstResponder()
case genderField:
emailField.becomeFirstResponder()
case emailField:
emailField.resignFirstResponder()
default:
break
}
return true
}
// namefield에 들어가는 글자를 최대 10자로 해보자
// ageField에는 최대한 1~100만 입력할 수 있도록 해보기
// genderField에는 문자 M F만 입력할 수 있도록 해보기
// emailField에는 email만 입력이 가능하게 해보기
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// 추가되긴 전 text
print("current: \(textField.text ?? "")")
// string -> 새롭게 추가될 문자
print("string: \(string)")
// textfield.text를 nsstring으로 만들어준다.
let currentText = NSString(string: textField.text ?? "")
let finalText = currentText.replacingCharacters(in: range, with: string)
switch textField {
case nameField:
if finalText.count > 10{
// 입력된 내용을 무시한다. 즉 추가가되지 않는다.
return false
}
case ageField:
// charSet에 없는 문자는 싹 다 제한을 시킨다!
if let _ = string.rangeOfCharacter(from: charSet){
return false
}
if let age = Int(finalText), !(1...100).contains(age) {
return false
}
// 글자도 한개만 가능하게, 그리고 MF만 입력이 가능하도록!
case genderField:
if let _ = string.rangeOfCharacter(from: invalidGenderCharSet){
return false
}
if finalText.count > 1 {
return false
}
default:
break
}
// true가 나와야지 textfield에서 최종적으로 추가가 된다.
return true
}
// Email을 맞는 포멧에만 입력이 가능하게!
// true를 return하면 편집상태를 종료한다!
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
if textField == emailField {
// 잘못된 email format일 경우 return false를 한다!
guard let email = textField.text, let _ = email.range(of: regex, options: .regularExpression) else {
alert(message: "invalid email")
return false
}
}
return true
}
}
extension TextDelegateViewController {
func alert(message: String) {
let alert = UIAlertController(title: "알림", message: message, preferredStyle: .alert)
let ok = UIAlertAction(title: "확인", style: .default, handler: nil)
alert.addAction(ok)
present(alert, animated: true, completion: nil)
}
}
아래와 같이 uiview를 dock에 넣어서 추가해주고 그 안에 pickerview를 추가해준다.
그리고 pickerview를 본 view에 datasource와 delegate으로 연결해준다.
Pickerview가 추가된 view를 outlet으로 설정해준다.
@IBOutlet var pickerContainterView: UIView!
extension InputViewViewController: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return 100
}
}
extension InputViewViewController: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return "\(row + 1)"
}
// 선택되면 해당 ageField.text를 변경해주기
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
ageField.text = "\(row + 1)"
}
}
override func viewDidLoad() {
super.viewDidLoad()
ageField.inputView = pickerContainterView
}
앞선 pickerview와 동일하게 새로운 view를 만들어준다.
f button의 태그를 1로 바꿔줘서 m과 구별할 수 있게 해준다.
outlet으로 추가해준다.
@IBOutlet var buttonContainerView: UIView!
@IBAction func selectGender(_ sender: UIButton) {
genderField.text = sender.tag == 0 ? "M" : "F"
UIDevice.current.playInputClick()
}
genderField.inputView = buttonContainerView
@IBOutlet var accessoryBar: UIToolbar!
ageField.inputAccessoryView = accessoryBar
genderField.inputAccessoryView = accessoryBar
nameField.inputAccessoryView = accessoryBar
@IBAction func movePrevious(_ sender: Any) {
if genderField.isFirstResponder {
ageField.becomeFirstResponder()
} else if ageField.isFirstResponder {
nameField.becomeFirstResponder()
}
}
@IBAction func moveNext(_ sender: Any) {
if nameField.isFirstResponder {
ageField.becomeFirstResponder()
} else if ageField.isFirstResponder{
genderField.becomeFirstResponder()
}
}