Klavyeyi devre dışı bırakmak istediğimde UITextField'ım ilk yanıtlayıcıyı istifa etmesini söylemem gerektiğini biliyorum, ancak kullanıcının klavyedeki "Bitti" tuşuna ne zaman bastığını bilmiyorum. İzleyebileceğim bir bildirim var mı?
Klavyeyi devre dışı bırakmak istediğimde UITextField'ım ilk yanıtlayıcıyı istifa etmesini söylemem gerektiğini biliyorum, ancak kullanıcının klavyedeki "Bitti" tuşuna ne zaman bastığını bilmiyorum. İzleyebileceğim bir bildirim var mı?
Yanıtlar:
Sınıfına delege UITextField
koydum ViewController
.
Bu sınıfta bu yöntemi aşağıdaki gibi uyguladım:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
NO
yerine geri dönelim YES
?
NO
metne satır dönüşü eklemekten kaçınırsınız.
Metin alanının DidEndOnExit olayını InterfaceBuilder'daki bir eyleme (IBAction) bağlarsanız, kullanıcı klavyeyi kapattığında (dönüş tuşu ile) ve gönderen olayı başlatan UITextField için bir referans olur.
Örneğin:
-(IBAction)userDoneEnteringText:(id)sender
{
UITextField theField = (UITextField*)sender;
// do whatever you want with this text field
}
Ardından, InterfaceBuilder'da, metin alanının DidEndOnExit olayını denetleyicinizdeki (veya kullanıcı arabirimindeki olayları bağlamak için ne kullanıyorsanız) bu eyleme bağlayın. Kullanıcı her metin girdiğinde ve metin alanını kapattığında, denetleyiciye bu mesaj gönderilir.
Denetleyicinizde bir yöntem de oluşturabilirsiniz
-(IBAction)editingEnded:(id)sender{
[sender resignFirstResponder];
}
ve ardından IB'deki Müfettiş'te Olay "Bittiğinde Çıkış Yapıldı" olayına bağlanır.
DidEndOnExit
Etkinliğe abone olarak, arama yapmanız gerekmez resignFirstResponder
. Bunu sembolik bir kesme noktası koyarak test edebilirsiniz [UIResponder resignFirstResponder]
. ResignFirstResponder çağırmasanız bile, yine de sistem tarafından çağrıldığını unutmayın. Bu Matt Neuburg'un
Kubi, teşekkürler. Kodunuz işe yaradı. Sadece açık olmak için (gibi yeni başlayanlar için) UITextField
's delegate
metin alanının bulunduğu ViewController eşit olacak şekilde ayarlamak zorunda. Bunu istediğiniz zaman yapabilirsiniz. viewDidLoad
Yöntemi seçtim .
- (void)viewDidLoad
{
// sets the textField delegates to equal this viewController ... this allows for the keyboard to disappear after pressing done
daTextField.delegate = self;
}
delegate
. Yukarıda gösterildiği gibi bunu programlı olarak yapmanız gerekmez. Her iki yaklaşım da işe yarar.
İşte hiç kod olmadan otomatik klavye işten çıkarma davranışını almak için bir hile. Uçta, Kimlik denetçisindeki İlk Yanıtlayıcı proxy nesnesini düzenleyerek yeni bir ilk yanıtlayıcı eylemi ekleyin; diyelim dummy:
. Şimdi metin alanının Çıkışta Sona Erdi olayını dummy:
İlk Yanıtlayıcı proxy nesnesinin eylemine bağlayın . Bu kadar! Metin alanının Çıkışta Sona Erdi olayı artık bir eylem-hedef çifti içerdiğinden, kullanıcı Return tuşuna dokunduğunda metin alanı klavyesini otomatik olarak kapatır; ve yanıtlayan zincirine gönderilen bir mesaj için bir işleyici bulamamaktan dolayı ceza olmadığından, hiçbir dummy:
yerde uygulama olmamasına rağmen uygulama çökmez .
Sadece ekle
[textField endEditing:YES];
klavyeyi devre dışı bırakmak ve seçici görünümünü görüntülemek istediğiniz yere.
Swift'te Denetleyiciye bir IBAction yazabilir ve metin alanının Çıkışta Sona Erdi olayını bu eyleme ayarlayabilirsiniz
@IBAction func returnPressed(sender: UITextField) {
self.view.endEditing(true)
}
Swift 4.2
ve% 100 çalışacak
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.textField.delegate = self
}
// hide key board when the user touches outside keyboard
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
// user presses return key
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
Ayrıca kullanabilirsiniz
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.yourTextField resignFirstResponder];
}
Çok sayıda Uitextfield'iniz varsa en iyisi:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
İşte işe yaraması için yapmam gerekenlerdi ve bence bir klavye için bir Sayısal Tuş Takımı (ya da bitmiş düğmesi olmayan başkaları için) gerekli:
Adlı bir işlev oluşturdum
-(IBAction)backgroundIsTapped:(id)sender
Bu, .h dosyasında da tanımlanmıştır.
Bundan sonra, Interface Builder'da ViewController için 'dokunma' bitine bağlandım.
'Arka plan dokunulur' işlevinde, ben koymak:
[answerField resignFirstResponder];
'AnswerField' öğesini klavyeyi kaldırmak istediğiniz UITextField'ın adıyla değiştirmeyi unutmayın (açıkça UITextField öğenizin aşağıdaki gibi tanımlandığından emin olun :)
IBOutlet UITextField * <nameoftextfieldhere>;
Bu konunun muhtemelen uzun zaman önce öldüğünü biliyorum ... ama bunun bir yerlerde birisine yardım edeceğini umuyorum!
"TextFieldShouldReturn" yönteminin DONE tuşuna basan metin alanı nesnesini sağladığını göreceksiniz. ETİKET'i ayarlarsanız bu metin alanını açabilirsiniz. Veya nesnenin işaretçisini, yaratıcısı tarafından saklanan bazı üye değerleriyle izleyebilir ve karşılaştırabilirsiniz.
Bireysel çalışma için yaklaşımım şöyle:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSLog(@"%s", __FUNCTION__);
bool fDidResign = [textField resignFirstResponder];
NSLog(@"%s: did %resign the keyboard", __FUNCTION__, fDidResign ? @"" : @"not ");
return fDidResign;
}
Bu arada istifa etmeyi reddeden "doğrulama" testini yaptım. Sadece gösterim içindir, bu nedenle kullanıcı NO yazıyorsa! sahaya girmezse, atmaz. Davranış istediğim gibiydi, ancak çıktı sırası beklediğim gibi değildi.
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
NSLog(@"%s", __FUNCTION__);
if( [[textField text] isEqualToString:@"NO!"] ) {
NSLog(@"%@", textField.text);
return NO;
} else {
return YES;
}
}
Bu reddi için NSLog çıktımı ve ardından kabulü aşağıdadır. İstifa sonucunu iade ettiğimi fark edeceksiniz, ancak arayan kişiye geri bildirmek için FALSE'i bana geri döndürmesini bekledim mi ?! Bunun dışında gerekli davranışa sahiptir.
13.313 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:] 13.320 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldEndEditing:] 13.327 ÇalışmaKbd [109: 207] HAYIR! 13.333 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:]: klavyeden istifa etti 59.891 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:] 59.897 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldEndEditing:] 59.917 StudyKbd [109: 207] - [StudyKbdViewController doneEditText]: HAYIR 59.928 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:]: klavyeden istifa etti
Dönüş Anahtarı veya arka planda bir dokunuşla baskıyı sonlandırmanın oldukça temiz bir yolu.
Interface builder'da alanlarınızı sınıf UIFormView görünümüne gömün
Bu sınıf ne yapar:
İşte kod:
Arayüz
#import <UIKit/UIKit.h>
@interface UIFormView : UIView<UITextFieldDelegate>
-(BOOL)textFieldValueIsValid:(UITextField*)textField;
-(void)endEdit;
@end
uygulama
#import "UIFormView.h"
@implementation UIFormView
{
UITextField* currentEditingTextField;
}
// Automatically register fields
-(void)addSubview:(UIView *)view
{
[super addSubview:view];
if ([view isKindOfClass:[UITextField class]]) {
if ( ![(UITextField*)view delegate] ) [(UITextField*)view setDelegate:self];
}
}
// UITextField Protocol
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
currentEditingTextField = textField;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
currentEditingTextField = NULL;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self endEdit];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if ([self textFieldValueIsValid:textField]) {
[self endEdit];
return YES;
} else {
return NO;
}
}
// Own functions
-(void)endEdit
{
if (currentEditingTextField) {
[currentEditingTextField endEditing:YES];
currentEditingTextField = NULL;
}
}
// Override this in your subclass to handle eventual values that may prevent validation.
-(BOOL)textFieldValueIsValid:(UITextField*)textField
{
return YES;
}
@end
Formu alt sınıflandırarak ve textFieldValueIsValid:
yöntemi geçersiz kılarak
, değer verilen alan için doğru değilse sürüm sonundan kaçınabilirsiniz.
Bir alanın Interface Builder'da ayarlanmış bir temsilcisi varsa, form alanı değiştirmez. Belirli bir alana farklı bir temsilci ayarlamak için pek çok neden göremiyorum, ama neden olmasın…
Bu form görünümü sınıfını iyileştirmenin birçok yolu vardır - Bir temsilci ekleyin, bazı düzenler yapın, klavyeler bir alanı kapladığında işlem yapın (currentEditingTextField çerçevesini kullanarak), sonraki alan için otomatik olarak sürümü başlat, ...
Şahsen bunu çerçevemde tutuyorum ve her zaman özellikler eklemek için alt sınıfta bırakıyorum, genellikle "olduğu gibi" kullanışlıdır.
Umarım yardımcı olur. Herkese şerefe
bir UIViewController tüm düzenleme istiyorsanız kullanabilirsiniz.
[[self view]endEditing:YES];
Pertiküler bir UITextField klavye gizlemesini kapatmak istiyorsanız kullanın.
1. görünümünüze temsilci ekleyin.
<UITextFieldDelegate>
yetkiyi metin alanınıza yapamaz hale getirin.
self.yourTextField.delegate = self;
bu yöntemi görünüm denetleyicinize ekleyin.
- (BOOL) textFieldShouldEndEditing: (UITextField *) textField {[textField resignFirstResponder]; dönüş YES;}
Programlı olarak UITextField temsilcisini hızlıca ayarlayın 3
ViewController.Swift dosyanıza UITextFieldDelegate uygulayın (örn. Sınıf ViewController: UIViewController, UITextFieldDelegate {)
lazy var firstNameTF: UITextField = {
let firstname = UITextField()
firstname.placeholder = "FirstName"
firstname.frame = CGRect(x:38, y: 100, width: 244, height: 30)
firstname.textAlignment = .center
firstname.borderStyle = UITextBorderStyle.roundedRect
firstname.keyboardType = UIKeyboardType.default
firstname.delegate = self
return firstname
}()
lazy var lastNameTF: UITextField = {
let lastname = UITextField()
lastname.placeholder = "LastName"
lastname.frame = CGRect(x:38, y: 150, width: 244, height: 30)
lastname.textAlignment = .center
lastname.borderStyle = UITextBorderStyle.roundedRect
lastname.keyboardType = UIKeyboardType.default
lastname.delegate = self
return lastname
}()
lazy var emailIdTF: UITextField = {
let emailid = UITextField()
emailid.placeholder = "EmailId"
emailid.frame = CGRect(x:38, y: 200, width: 244, height: 30)
emailid.textAlignment = .center
emailid.borderStyle = UITextBorderStyle.roundedRect
emailid.keyboardType = UIKeyboardType.default
emailid.delegate = self
return emailid
}()
// İşaretle: - temsilci textField'i kullanma ..
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == firstNameTF {
lastNameTF.becomeFirstResponder()
}
else if textField == lastNameTF {
emailIdTF.becomeFirstResponder()
}
else {
view.emailIdTF(true)
}
return true
}
Bir hidekeyboard işlevi oluşturun ve bunu .xib dosyasındaki metin alanına bağlayın ve DidEndOnExit'i seçin
-(IBAction)Hidekeyboard
{
textfield_name.resignFirstResponder;
}
Görünümü Interface Builder'ı kullanarak oluşturduysanız, Aşağıdakileri kullanın Sadece bir yöntem oluşturun,
-(IBAction)dismissKeyboard:(id)sender
{
[sender resignFirstResponder];
}
Görünümdeki metin alanını sağ tıklayın ve etkinliği Çıkışta Bitti olarak ayarlayın ve "dismissKeyboard" yöntemine bağlayın.
Yeni başlayanlar için en iyi rehber "İlk iPhone ve iPad Geliştirme, 2. Sürüm"
bunu dene
- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
{
if ([text isEqualToString:@"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
//====================================================
// textFieldShouldReturn:
//====================================================
-(BOOL) textFieldShouldReturn:(UITextField*) textField {
[textField resignFirstResponder];
if(textField.returnKeyType != UIReturnKeyDone){
[[textField.superview viewWithTag: self.nextTextField] becomeFirstResponder];
}
return YES;
}
Swift 3 arayan herkes
1) UITextField Temsilcinizin Storyboard'daki ViewController'ınıza bağlı olduğundan emin olun
2) ViewController.Swift dosyanıza UITextFieldDelegate uygulayın (örn. Sınıf ViewController: UIViewController, UITextFieldDelegate {)
3) Aşağıdaki temsilci yöntemini kullanın
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return false }
Swift 4.2'de klavyeyi bu şekilde kapatıyorum ve benim için çalışıyor:
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action:
#selector(dismissKeyboard))
view.addGestureRecognizer(tap)
}
@objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
numberField.resignFirstResponder()
}
Swift 3, iOS 9+
@IBAction private func noteFieldDidEndOnExit(_ sender: UITextField) {}
UPD: Benim için hala iyi çalışıyor. Bence bu cevabı adayan adam, bu eylemi hikaye tahtasındaki UITextField'e bağlaması gerektiğini anlamıyordu.