iOS 키보드 '완료' 버튼으로 텍스트 필드 순차 이동 구현하기
iPhone 앱에서 회원가입 폼처럼 여러 개의 텍스트 필드가 있을 때, 키보드의 '완료(Done)' 또는 '리턴(Return)' 버튼을 누를 때마다 다음 입력 칸으로 자동으로 포커스가 이동하면 사용자 경험이 크게 향상됩니다. 이를 구현하려면 각 텍스트 필드에 고유한 태그(tag)를 부여하고, 델리게이트 메서드 안에서 다음 필드를 찾아 포커스를 옮기는 로직을 작성해야 합니다.
실제 프로젝트 예제를 통해 단계별로 살펴보겠습니다.
1. 프로젝트 생성 및 UI 구성
- Xcode에서 새 프로젝트를 만들고, 스토리보드의 뷰 컨트롤러 위에 텍스트 필드 4개를 배치합니다.
- 텍스트 필드를 하나씩 선택한 뒤 어트리뷰트 인스펙터(Attribute Inspector)에서 Tag 값을 각각 1, 2, 3, 4로 설정합니다.
- 같은 인스펙터에서 Return Key 항목을 'Done'으로 변경합니다.
2. 아울렛(Outlet) 연결
뷰 컨트롤러 클래스에 네 개의 텍스트 필드에 대한 아울렛을 생성하고, 스토리보드의 각 요소와 연결합니다.
@IBOutlet weak var tf1: UITextField!
@IBOutlet weak var tf2: UITextField!
@IBOutlet weak var tf3: UITextField!
@IBOutlet weak var tf4: UITextField!3. UITextFieldDelegate 채택 및 델리게이트 설정
ViewController 클래스를 확장(Extension)하여 UITextFieldDelegate를 채택하고, 리턴 버튼 동작을 처리할 textFieldShouldReturn 메서드를 작성합니다.
extension ViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool { }
}이어서 viewDidLoad() 메서드에서 각 텍스트 필드의 delegate를 self로 지정합니다.
override func viewDidLoad() {
super.viewDidLoad()
self.tf1.delegate = self
self.tf2.delegate = self
self.tf3.delegate = self
self.tf4.delegate = self
}4. 다음 텍스트 필드로 포커스 이동하는 로직
textFieldShouldReturn 메서드에 아래 코드를 추가합니다. 현재 텍스트 필드의 태그에 1을 더한 값으로 다음 뷰를 찾고, 해당 뷰가 존재하면 becomeFirstResponder()를 호출해 포커스를 이동시킵니다. 마지막 필드라면 resignFirstResponder()로 키보드를 내립니다.
let nextTag = textField.tag + 1
let nextTF = textField.superview?.viewWithTag(nextTag) as UIResponder!
if nextTF != nil {
nextTF?.becomeFirstResponder()
} else {
textField.resignFirstResponder()
}
return false5. 완성된 ViewController 전체 코드
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tf1: UITextField!
@IBOutlet weak var tf2: UITextField!
@IBOutlet weak var tf3: UITextField!
@IBOutlet weak var tf4: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.tf1.delegate = self
self.tf2.delegate = self
self.tf3.delegate = self
self.tf4.delegate = self
}
}
extension ViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let nextTag = textField.tag + 1
let nextTF = textField.superview?.viewWithTag(nextTag) as UIResponder!
if nextTF != nil {
nextTF?.becomeFirstResponder()
} else {
textField.resignFirstResponder()
}
return false
}
}아래 이미지는 Xcode 편집 화면과 시뮬레이터에서 실제로 동작하는 모습입니다.


추가 팁
이 방식은 태그 번호만 순서대로 지정하면 되므로 필드가 많아져도 손쉽게 확장할 수 있습니다. 반대로 이전 필드로 돌아가려면 태그에서 1을 빼는 로직을 추가하면 됩니다. 또한 서드파티 라이브러리인 IQKeyboardManager를 사용하면 코드 없이도 키보드 관련 UX(포커스 이동, 화면 스크롤 등)를 자동으로 처리할 수 있으니 참고하세요.