UITextField เป็นคอมโพเนนต์ UIKit มาตรฐานสำหรับการป้อนข้อความบรรทัดเดียวใน iOS ที่สืบทอดจาก UIControl และรองรับโหมดแป้นพิมพ์ที่หลากหลาย ตามเอกสารของ Apple Developer (2025) UITextField มี delegate UITextFieldDelegate พร้อม callback shouldBeginEditing, shouldChangeCharactersInRange และ shouldReturn แตกต่างจาก UITextView ตรงที่ UITextField จำกัดอินพุตไว้ที่บรรทัดเดียวและรองรับ secureTextEntry, leftView และ rightView สำหรับคอนโทรลแบบกำหนดเอง นี่คือ องค์ประกอบหลัก สำหรับฟอร์มการยืนยันตัวตน การค้นหา การลงทะเบียน และการป้อนข้อมูลในแอปพลิเคชัน iOS
ประเด็นสำคัญ
UITextField เป็นคลาสของเฟรมเวิร์ก UIKit ที่ออกแบบมาสำหรับการป้อนข้อความบรรทัดเดียวโดยผู้ใช้ คลาสสืบทอดจาก UIControl ซึ่งอนุญาตให้สมัครรับอีเวนต์อินพุตผ่านกลไก target-action: addTarget(self, action: Selector("textChanged:"), for: editingChanged) UITextField แสดงขอบ (borderStyle) ข้อความ placeholder เมื่อช่องว่าง ปุ่มล้าง (clearButtonMode) และสามารถมีมุมมองเสริมด้านซ้าย/ขวา ช่องจะแสดง/ซ่อนแป้นพิมพ์โดยอัตโนมัติเมื่อได้รับ/สูญเสียโฟกัสผ่าน becomeFirstResponder และ resignFirstResponder ขนาดของช่องถูกกำหนดโดย intrinsicContentSize ตามแบบอักษรและสไตล์ขอบ ในการสร้าง UITextField ใน Interface Builder (Storyboard/XIB) ให้ใช้ Object Library โดยทางโปรแกรมให้ใช้ตัวเริ่มต้น UITextField(frame: CGRect) คลาสนี้เข้ากันได้อย่างสมบูรณ์กับสถาปัตยกรรม iOS สมัยใหม่: Combine publishers, @Published ใน SwiftUI ผ่าน UIViewRepresentable และ Diffable Data Source สำหรับฟอร์ม
UITextField รองรับ 12 ประเภทแป้นพิมพ์ผ่านคุณสมบัติ keyboardType แต่ละประเภทปรับชุดอักขระให้เหมาะสมสำหรับสถานการณ์อินพุตเฉพาะ UIKeyboardType.default — แป้นพิมพ์ QWERTY มาตรฐาน UIKeyboardType.numberPad — เฉพาะตัวเลขไม่มีสัญลักษณ์เพิ่มเติม (เหมาะสำหรับรหัส PIN และหมายเลขโทรศัพท์) UIKeyboardType.emailAddress — แป้นพิมพ์ที่มี @ และจุดบนเลเยอร์หลัก UIKeyboardType.URL — แป้นพิมพ์ที่มี .com, / และจุดบนเลเยอร์หลัก UIKeyboardType.phonePad — แป้นพิมพ์ตัวเลขที่มี +, *, # สำหรับป้อนหมายเลขโทรศัพท์ UIKeyboardType.decimalPad — ตัวเลขที่มีจุดทศนิยมสำหรับป้อนราคา UIKeyboardType.webSearch — แป้นพิมพ์ที่มีปุ่ม Go ที่ปรับให้เหมาะสมสำหรับคำค้นหา UIKeyboardType.asciiCapable — เฉพาะอักขระ ASCII สำหรับข้อความละติน แป้นพิมพ์จะปรากฏเมื่อเรียก becomeFirstResponder และซ่อนเมื่อเรียก resignFirstResponder ประเภทแป้นพิมพ์สามารถเปลี่ยนแปลงได้แบบไดนามิกระหว่างการแก้ไข
| ประเภท | สถานการณ์ | คุณสมบัติ |
|---|---|---|
| default | ป้อนข้อความทั่วไป | QWERTY มาตรฐาน |
| numberPad | PIN, รหัส | เฉพาะตัวเลข 0-9 |
| emailAddress | อีเมล | @ และ . บนเลเยอร์หลัก |
| URL | ที่อยู่เว็บ | .com, /, . บนหลัก |
| phonePad | โทรศัพท์ | ตัวเลข, +, *, # |
| decimalPad | ราคา, ตัวเลข | ตัวเลข + จุดทศนิยม |
UITextFieldDelegate เป็นโปรโตคอลที่กำหนดพฤติกรรมของช่องข้อความในขั้นตอนต่างๆ ของอินพุต เมธอดหลัก: textFieldShouldBeginEditing(textField) — ส่งคืน Bool ที่อนุญาตหรือปฏิเสธการเริ่มแก้ไข; textFieldDidBeginEditing — ถูกเรียกหลังจากแป้นพิมพ์ปรากฏ; textFieldShouldEndEditing — ตรวจสอบว่าสามารถแก้ไขเสร็จสิ้นได้หรือไม่ (ถ้า false ช่องจะไม่เสียโฟกัส); textFieldDidEndEditing — ถูกเรียกหลังจากแป้นพิมพ์ซ่อน; textFieldShouldChangeCharactersInRange — ถูกเรียกทุกครั้งที่ป้อนอักขระ อนุญาตให้กรองอินพุต (อนุญาตเพียงอักขระเดียว ถ้าส่งคืน false — อักขระจะไม่ถูกเพิ่ม); textFieldShouldReturn — ถูกเรียกเมื่อกด Return/Go/Next/Search ใช้เพื่อย้ายไปยังช่องถัดไป Delegate ไม่ใช่ Optional: ทุกเมธอดมีการใช้งานเริ่มต้น แต่สำหรับพฤติกรรมที่กำหนดเอง คุณต้องแทนที่เมธอดที่เกี่ยวข้อง
เมธอด shouldReturn เป็นรูปแบบมาตรฐานสำหรับการนำทางระหว่างช่องฟอร์ม การใช้งาน: textFieldShouldReturn(textField) — ตรวจสอบว่า textField ใดทริกเกอร์อีเวนต์และย้ายโฟกัสไปยังช่องถัดไปผ่าน becomeFirstResponder() ถ้าเป็นช่องสุดท้าย ให้เรียก resignFirstResponder() เพื่อซ่อนแป้นพิมพ์ ใช้ IBOutlet collection หรือ IBOutlet แยกสำหรับแต่ละช่องเพื่อเก็บข้อมูลอ้างอิงช่อง
isSecureTextEntry — คุณสมบัติของ UITextField ที่เมื่อเป็น true จะแทนที่อักขระที่ป้อนด้วยจุด (•) และบล็อกการคัดลอกข้อความผ่าน UIMenuController ใช้สำหรับช่องรหัสผ่าน รหัส PIN, CVV เมื่อสลับระหว่างโหมดปลอดภัยและข้อความธรรมดา (show/hide password) ให้ตั้งค่า textField.isSecureTextEntry.toggle() สำคัญ: เมื่อเปลี่ยน isSecureTextEntry ข้อความในช่องจะถูกรีเซ็ต — ให้บันทึกไว้ล่วงหน้า LeftView และ RightView เป็น UIView แบบกำหนดเองที่แสดงภายในช่องป้อนข้อมูลทางซ้ายหรือขวา การใช้งานทั่วไป: ไอคอนค้นหาใน leftView, ปุ่ม "ล้าง" ใน rightView การกำหนดค่า: textField.leftViewMode = always (เสมอ) หรือ whileEditing (เฉพาะระหว่างแก้ไข) left/right view จะถูกวางตำแหน่งโดยอัตโนมัติภายในช่องข้อความโดยคำนึงถึงระยะห่าง ขนาดของ view ถูกกำหนดผ่าน bounds หรือ Auto Layout
import UIKit
class LoginViewController: UIViewController {
let passwordField = UITextField()
override func viewDidLoad() {
super.viewDidLoad()
passwordField.isSecureTextEntry = true
passwordField.placeholder = "Password"
passwordField.keyboardType = .asciiCapable
passwordField.delegate = self
// ปุ่มแสดง/ซ่อนรหัสผ่านแบบกำหนดเอง
let showButton = UIButton(type: .system)
showButton.setTitle("แสดง", for: .normal)
showButton.addTarget(self, action: #selector(togglePasswordVisibility),
for: .touchUpInside)
passwordField.rightView = showButton
passwordField.rightViewMode = .always
}
@objc func togglePasswordVisibility() {
passwordField.isSecureTextEntry.toggle()
}
}
UITextInputTraits เป็นโปรโตคอลที่กำหนดลักษณะที่ปรากฏทางภาพและพฤติกรรมของแป้นพิมพ์สำหรับ UITextField คุณสมบัติหลัก: autocorrectionType (.default, .no, .yes) — เปิดหรือปิดการแก้ไขข้อความอัตโนมัติ; autocapitalizationType (.none, .words, .sentences, .allCharacters) — ตัวพิมพ์ใหญ่ อัตโนมัติสำหรับอักขระแรก; spellCheckingType — การตรวจสอบการสะกด; returnKeyType (.done, .go, .next, .search, .send, .continue, .join, .route, .emergencyCall) — ข้อความปุ่ม Return บนแป้นพิมพ์; enablesReturnKeyAutomatically — การปิดใช้งานปุ่ม Return อัตโนมัติเมื่อช่องว่าง สำหรับช่องป้อนชื่อ ให้ใช้ autocapitalizationType = .words สำหรับอีเมล ให้ใช้ autocorrectionType = .no สำหรับ URL ให้ใช้ keyboardType = .URL + autocapitalizationType = .none การกำหนดค่า traits จะดำเนินการหลังจากการเริ่มต้นช่องก่อนที่จะแสดง การเปลี่ยน traits แบบไดนามิกจะอัปเดตแป้นพิมพ์เมื่อปรากฏครั้งถัดไป
Return Key Type กำหนดข้อความปุ่มบนแป้นพิมพ์: Next — ไปยังช่องถัดไป, Done — เสร็จสิ้นอินพุต, Search — เริ่มค้นหา, Send — ส่งฟอร์ม, Continue — ดำเนินการกรอกต่อ เมื่อรวมกับเมธอด delegate shouldReturn แล้ว returnKeyType ช่วยให้ UX เป็นธรรมชาติ: ผู้ใช้กรอกข้อมูลในช่อง กด Next เพื่อไปยังช่องถัดไป และกด Done เพื่อส่งในช่องสุดท้าย สำหรับการปรับแต่งข้อความปุ่ม ให้ใช้ UIButtonConfiguration ใน iOS 15+
Placeholder ของ UITextField คือข้อความที่แสดงเป็นสีเทาเมื่อช่องว่าง การกำหนดค่า: textField.placeholder = "Enter email" สำหรับปรับแต่งสีและแบบอักษรของ placeholder ให้ใช้ attributedPlaceholder กับ NSAttributedString มาสก์อินพุต ถูกใช้งานผ่านเมธอด delegate shouldChangeCharactersInRange — รองรับรูปแบบหมายเลขโทรศัพท์ วันที่ บัตรเครดิต และ SNILS มาสก์อินพุตช่วยแยกการแสดงผลออกจากค่า: ผู้ใช้เห็นข้อความที่จัดรูปแบบ (เช่น +7 (999) 999-99-99) ในขณะที่โมเดลเก็บ "79999999999" ตัวอย่างการใช้งาน: เก็บมาสก์เป็นสตริงที่มีอักขระ X สำหรับการแทนที่; ในแต่ละอินพุต ให้สร้างสตริงที่จัดรูปแบบและส่งคืน false ใน shouldChangeCharactersInRange โดยแทนที่ข้อความช่องผ่าน textField.text = formattedText สำหรับตัวเลข ให้ใช้ NumberFormatter และ keyboardType แบบทศนิยม
extension LoginViewController: UITextFieldDelegate {
func textFieldShouldReturn(
textField: UITextField
) -> Bool {
if textField == emailField {
passwordField.becomeFirstResponder()
} else if textField == passwordField {
textField.resignFirstResponder()
loginTapped()
}
return true
}
func textField(
textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String
) -> Bool {
// บล็อกช่องว่างในอีเมล
if textField == emailField && string == " " {
return false
}
// จำกัดความยาวรหัสผ่าน
if textField == passwordField {
let newLength = (textField.text?.count ?? 0) +
string.count - range.length
return newLength <= 32
}
return true
}
}
มาดูตัวอย่างที่สมบูรณ์ของการใช้งานฟอร์มเข้าสู่ระบบด้วย UITextField การตรวจสอบอีเมล และการตอบกลับทางภาพ ฟอร์มประกอบด้วยสองช่อง: emailField (แป้นพิมพ์ emailAddress, ไม่มีการแก้ไขอัตโนมัติ) และ passwordField (secureTextEntry) การตรวจสอบจะดำเนินการใน shouldChangeCharactersInRange และเพิ่มเติมเมื่อกดปุ่ม Login สำหรับการตอบกลับทางภาพ: ขอบสีแดง (layer.borderColor) เมื่อเกิดข้อผิดพลาด สีเขียว — เมื่อตรวจสอบสำเร็จ รีเซ็ตขอบเมื่อเริ่มแก้ไขใน textFieldDidBeginEditing
การตรวจสอบอีเมล ดำเนินการผ่าน NSPredicate ด้วยรูปแบบ "SELF MATCHES %@" และนิพจน์ปกติสำหรับการตรวจสอบรูปแบบพื้นฐาน การตรวจสอบการมีอยู่จริงของอีเมลควรดำเนินการบนเซิร์ฟเวอร์ สำหรับการตรวจสอบขั้นสูง ให้ใช้ไลบรารี SwiftValidators หรือ Combine publishers ตัวอย่าง: NSPredicate(format: "SELF MATCHES [c] %@", emailRegex).evaluate(with: email) ขอบของช่องถูกอัปเดตผ่านบล็อกแอนิเมชันเพื่อการเปลี่ยนที่ราบรื่น
func validateEmail(textField: UITextField) {
guard let text = textField.text, !text.isEmpty else {
textField.layer.borderColor = UIColor.clear.cgColor
return
}
let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.\\p{L}{2,}"
let predicate = NSPredicate(format: "SELF MATCHES [c] %@", emailRegex)
let isValid = predicate.evaluate(with: text)
UIView.animate(withDuration: 0.2) {
textField.layer.borderColor = isValid
? UIColor.systemGreen.cgColor
: UIColor.systemRed.cgColor
textField.layer.borderWidth = 1.0
textField.layer.cornerRadius = 6.0
}
}
คำถามที่พบบ่อย
ใช้เมธอด delegate shouldChangeCharactersInRange คำนวณความยาวข้อความใหม่เป็น existingText.count + newText.count - range.length และส่งคืน false หากเกินขีดจำกัด อีกทางเลือก: สมัครรับอีเวนต์ editingChanged ผ่าน addTarget และตัดข้อความโดยใช้ textField.text = String(text.prefix(maxLength))
ตรวจสอบ: isUserInteractionEnabled = true (ค่าเริ่มต้น), delegate ไม่ส่งคืน false ใน shouldBeginEditing หากช่องอยู่ใน UIScrollView ให้ปิดการใช้งาน delaysContentTouches หากช่องอยู่ในตัวควบคุมโมดอล ให้ตรวจสอบว่าไม่ได้บล็อกการสัมผัส สำหรับ SwiftUI UIViewRepresentable ให้ตรวจสอบว่าช่องกลายเป็น firstResponder อย่างถูกต้องผ่าน DispatchQueue.main.async
เพิ่ม UITapGestureRecognizer บน self.view หรือ scrollView ด้วย target-action ที่เรียก view.endEditing(true) อีกทางเลือก: textField.resignFirstResponder() เพื่อซ่อนแป้นพิมพ์ของช่องเฉพาะ ใช้ touchesBegan ใน UIViewController หรือใช้ไลบรารี IQKeyboardManager สำหรับการจัดการแป้นพิมพ์อัตโนมัติ อย่าลืมปิดการใช้งาน cancelsTouchesInView เพื่อให้ปุ่มทำงานอย่างถูกต้อง
สีข้อความ: textField.textColor = UIColor.label แบบอักษร: textField.font = UIFont.systemFont(ofSize: 16, weight: .regular) สี placeholder: textField.attributedPlaceholder = NSAttributedString(string: "Email", attributes: [.foregroundColor: UIColor.secondaryLabel])
สามวิธี: isEnabled = false (เปลี่ยนลักษณะที่ปรากฏ), isUserInteractionEnabled = false (คงสไตล์ภาพไว้) หรือส่งคืน false ใน delegate textFieldShouldBeginEditing วิธีที่สามดีกว่า — มันบล็อกอินพุตโดยไม่เปลี่ยนสไตล์ภาพ สำหรับการตั้งค่าข้อความโดยทางโปรแกรมในโหมดอ่านอย่างเดียว ให้ใช้ delegate
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม