UITableView'ın arka planına dokunarak klavyeyi kapatın


105

Bir var UITableViewolan UITextFieldhücreleri olarak s. Arka planına UITableViewdokunulduğunda klavyeyi kapatmak istiyorum . Bunu, ' UIButtonnin bir boyutunu oluşturarak UITableViewve bunu UITableView. Tek sorun, UIButtondokunma UITableView üzerindeyken bile tüm dokunuşları yakalamaktır. Neyi yanlış yapıyorum?

Teşekkürler!


İlgili sorular ve cevaplar: S1 , Q2 , S3 .
Yantao Xie

Yanıtlar:


203

Bu, bir UITapGestureRecognizer nesnesi oluşturularak kolayca yapılabilir (varsayılan olarak bu, tek bir dokunuşta bir "hareketi" algılar, böylece daha fazla özelleştirme gerekmez), hareketin ne zaman tetikleneceği için bir hedef / eylem belirleyerek ve ardından hareket tanıyıcı nesnesini ekleyerek tablo görünümünüze.

Örneğin, viewDidLoadyönteminizde belki :

UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];

Ve hideKeyboardyöntemi şöyle olabilir:

- (void) hideKeyboard {
    [textField1 resignFirstResponder];
    [textField2 resignFirstResponder];
    ...
    ...
}

Bir UITextFieldnesnenin içine dokunulduğunda hareketin ateşlenmediğini unutmayın . Bu üzerinde olsa tetiklenir UITableViewarka plan, alt görünümü, başlık görünümü ve üzerinde UILabelsvs. iç hücrelerin


4
Bunu denediğimde, tablonun hücreleri seçmesini engellediğini fark ettim :(. Aksi takdirde harika bir çözüm
Brian

109
gestureRecognizer.cancelsTouchesInView = NO;
Aşağıda

3
Ve tableView'e eklendikten sonra, hareketRecognizer'ı bırakmayı da unutmayın.
Paul Lynch

39
İçin hideKeyboardyöntemin, metin alanları ile doğrudan iletişim yerine yapabileceğiniz [self.view endEditing:NO];. Apple belgelerinden: " Bu yöntem, şu anda ilk yanıt veren metin alanı için geçerli görünüme ve alt görünüm hiyerarşisine bakar. Bir tane bulursa, bu metin alanından ilk yanıtlayıcı olarak istifa etmesini ister. Force parametresi olarak ayarlanmışsa EVET, metin alanı asla sorulmaz; istifa etmek zorunda kalır. "
Gobot

1
bu şekilde kullandığımda "didSelectRowAtIndexPath" yöntemim çağrılmıyor. bunun için herhangi bir çözüm?
uniruddh

127

UITapGestureRecognizer çözümü, şunları ayarlarsanız tablo hücresi seçimiyle çalışır:

gestureRecognizer.cancelsTouchesInView = NO;

1
Bu, hücreye dokunmaya izin verir, ancak jest de tanınır, belki de bu temsilci yöntemlerini uygulamalıyızshouldReceiveTouch
onmyway133

61

İşte bunu yapmanın en iyi yolu. Sadece bunu yap

[self.view endEditing:YES];

veya

[[self.tableView superView] endEditing:YES];

bu kodu nereye koymalıyım? üzgünüm acemiyim. Ve lütfen hızlı kodu sağlayın.
John

54

Bunu Storyboard'dan da yapabilirsiniz: görüntü açıklamasını buraya girin


1
Ne seçersem seçeyim: Sürüklerken kapat, Etkileşimli Olarak Kapat, tablo hücresine dokunduğumda seçiliyor. Xcode 8 kullanıyorum, hızlı 3. lütfen yardım edin
John

22

As UITableViewbir alt sınıfıdır UIScrollViewtek temsilci yöntemi aşağıda son derece kolay, hızlı çözüm sağlar uygulanması. resignFirstResponderHiyerarşi iç gözlemlerini görüntülediğinden ve mevcut yanıtlayanı bulduğundan ve ondan yanıt veren statüsünden istifa etmesini istediğinden dahil olmaya bile gerek yok .

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.view endEditing:YES];
}

Ve UIScrollViewDelegatebaşlık dosyasına eklemeyi unutmayın .


2
Bu, iOS7 ve üstünü hedefliyorsanız @Joe Masilotti'nin belirttiği gibi bu tek hat aracılığıyla yapılabilir: self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
atulkhatri

Klavyeyi göstermek için yukarı kaydırması gereken ekranın altındaki bir metin alanına dokunursanız ne olur? - Klavyeniz gizlenecek.
İslam Q.

Swift 4 - self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.onDrag
RobLabs

13

Öncelikle, dinler scrollViewWillBeginDraggingGözlerinde farklı UIViewControllerekleyerek UIScrollViewDelegate:

.H dosyasında:

@interface MyViewController : UIViewController <UIScrollViewDelegate> 

.M dosyasında:

- (void)scrollViewWillBeginDragging:(UIScrollView *)activeScrollView {

    [self dismissKeyboard];

}

Ardından diğer etkileşimleri dinleyin:

- (void)setupKeyboardDismissTaps {

    UISwipeGestureRecognizer *swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeUpGestureRecognizer.cancelsTouchesInView = NO;
    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
    [self.tableView addGestureRecognizer:swipeUpGestureRecognizer];

    UISwipeGestureRecognizer *swipeDownGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeDownGestureRecognizer.cancelsTouchesInView = NO;
    swipeDownGestureRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
    [self.tableView addGestureRecognizer:swipeDownGestureRecognizer];

    UISwipeGestureRecognizer *swipeLeftGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeLeftGestureRecognizer.cancelsTouchesInView = NO;
    swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.tableView addGestureRecognizer:swipeLeftGestureRecognizer];

    UISwipeGestureRecognizer *swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeRightGestureRecognizer.cancelsTouchesInView = NO;
    swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
    [self.tableView addGestureRecognizer:swipeRightGestureRecognizer];


    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    tapGestureRecognizer.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tapGestureRecognizer];

}

Ardından uygulayın dismissKeyboard:

- (void)dismissKeyboard {

    NSLog(@"dismissKeyboard");

    [yourTextFieldPointer resignFirstResponder];

}

Ve benim gibi, özel bir tablo hücresi içindeki bir UITextField için klavyeyi kapatmak istediyseniz:

- (void)dismissKeyboard {

    NSLog(@"dismissKeyboard");

    CustomCellClass *customCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    [customCell.textFieldInCell resignFirstResponder]; 

}

Umarım arayan herkes yardımcı olur !!



8

İşte kodlama zevkiniz için hızlı sürüm:

Bir dokunma hareketi tanıyıcı ekler ve ardından klavyeyi kapatır. TextField için çıkış gerekmez!

override func viewDidLoad() {
    super.viewDidLoad()
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "handleTap:"))
}

func handleTap(sender: UITapGestureRecognizer) {
    if sender.state == .Ended {
        view.endEditing(true)
    }
    sender.cancelsTouchesInView = false
}

1
Bu, özel bir tableViewCell ile bile çalışır! Bunu anlamaya çalışmak için çok zaman harcadım. Çok teşekkür ederim! Kahramanımsın. youtu.be/EqWRaAF6_WY
peacetype

8

Hücrelerdeki tıklamaları engellemeyen Swift 3 sürümü var.

İn viewDidLoad()yöntemi:

let dismissKeyboardGesture = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
dismissKeyboardGesture.cancelsTouchesInView = false
tableView.addGestureRecognizer(dismissKeyboardGesture)

Ve hideKeyboardşuna benzer:

func hideKeyboard() {
    view.endEditing(true)
}

7

Ben böyle yaptım:

İlk yanıtlayanı devre dışı bırakmak için TableViewController'ınızda bir yöntem oluşturun (bu, o noktada TextBox'ınız olacaktır)

- (BOOL)findAndResignFirstResonder:(UIView *)stView {
    if (stView.isFirstResponder) {
        [stView resignFirstResponder];
        return YES;     
    }

    for (UIView *subView in stView.subviews) {
        if ([self findAndResignFirstResonder:subView]) {
            return YES;
        }
    }
    return NO;
}

Gelen tableView:didSelectRowAtIndexPath:önceki yöntemini çağırın:

- (void)tableView:(UITableView *)tableView
                             didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    [self findAndResignFirstResonder: self.view];
    ...
}

İstediğin şekilde yanlış yapıyorsun. görünüme bir düğme koymazsanız, görünüme bu cevabın dediği gibi klavyeyi kaldırmasını söylersiniz

2
Bu, bir tablo görünümü hücresine (ve bu tablo görünümü hücresi içindeki herhangi bir UITextField dışına) dokunursanız güzel çalışır. Ancak, masa görünümünün arka planına dokunursam (ki bu genellikle ulaşmak için daha kolay bir hedeftir - yay Fitts Yasası!), Böyle bir şans olmaz. Doğru, bu beklenen, çünkü bu işlemi tableView: didSelectRowAtIndexPath: içinde gerçekleştiriyoruz. Bu, bir şekilde tablo görünümünde başka herhangi bir yere dokunarak çalışacak şekilde ayarlanabilirse (bu, aksi takdirde klavye odağı istemez), burada bir kazananımız olduğunu düşünüyorum!
Joe D'Andrea

Jdandrea ile aynı sorunu yaşıyorum. Yani didSelectRowAtIndexPathsen TableView kendisi dokunursanız yangın yok.
zekel

didSelectRowAtIndexPath yeterli değilse, touchesBegan'da da aynısını yapın!
Amogh Talpallikar

5

Bir vardı UITableViewControllerve uygulama touchesBegan:withEvent:benim için işe yaramadı.

İşte ne işe yaradı:

Swift:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    view.endEditing(true)
}

Amaç-C:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.view endEditing:YES];
}

İyi fikir, beğendim.
HotFudgeSunday

4
@interface DismissableUITableView : UITableView {
}
@end

@implementation DismissableUITableView

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
 [self.superview endEditing:YES];
 [super touchesBegan:touches withEvent:event];
}

@end

Sonra Nib dosyanızda UITableView'ınızın türünü DismissableUITableView olarak ayarladığınızdan emin olun ..... belki bu sınıf için daha iyi bir isim düşünebilirdim, ama sen anladın.


4

İOS7'yi hedefliyorsanız aşağıdakilerden birini kullanabilirsiniz:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

İlki, tablo görünümü kaydırıldığında klavyeyi ekran dışı hareketlendirecek ve daha sonra, hisse senedi Mesajları uygulaması gibi klavyeyi gizleyecektir.

Bunların olduğunu unutmayın UIScrollViewki, UITableViewdevralır.


Güzel. Klavye aşağı hareket etmeye başlayana kadar ekranın yukarısından aşağı doğru kaydırarak, ardından klavye biraz yukarı çıkıncaya kadar tekrar yukarı kaydırıp sonra bırakarak bir tür kırmayı başardım. kaydırma görünümü olması gerektiği gibi en üste geri dönmez.
Sam

3

Bunu dene:

viewDidLoad(){

    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))

    tableView.addGestureRecognizer(tap)

}
//Calls this function when the tap is recognized.
@objc func dismissKeyboard() {

    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    view.endEditing(true)

}

2

UITableView, UIScrollView'ın bir alt sınıfıdır.

Bunu yaptığım yol, kullanıcı tarafından bir kaydırma olayını dinlemek ve ardından İlkResponder'ı bırakmaktı. Kodunuzda uygulamak için UIScrollViewDelegate yöntemi burada;

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

Bu tür sorunlara yaklaşırken bulduğum en iyi yol, her nesne ve üst sınıflar için temsilci protokollerini araştırmaktır (bu durumda UITableViewDelegate, UIScrollViewDelegate. NS nesnelerinin tetiklediği olayların sayısı oldukça büyük ve kapsamlıdır. ayrıca bir protokolü uygulamak ve sonra herhangi bir şeyi alt sınıflara ayırmak daha kolaydır.


2

Aynı sorunu yaşadım ve işte çözümüm, benim için mükemmel çalışıyor:

Uyguladığınız görünüm veya görünüm denetleyicisinde <UITextFieldDelegate>

(Benim durumumda UITableViewCellTextFieldCell adında bir özelliğim var ),

UITapGestureRecognizerBir mülk olarak beyan edin :

@interface TextFieldCell : UITableViewCell <UITextFieldDelegate>
{
    UITextField *theTextField;
    UITapGestureRecognizer *gestureRecognizer;
}
@property (nonatomic,retain) UITextField *theTextField;
@property (nonatomic,retain) UITapGestureRecognizer *gestureRecognizer; 

Ve bunu görünümünüzde / denetleyicinizde başlatın:

self.gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyboard:)];

In - (void)textFieldDidBeginEditing:(UITextField *)textFieldyöntemle, kullanım superViewiçin tableView ve çağrısına yukarı taşımak için addGestureRecognizer:

[self.superview.superview addGestureRecognizer:gestureRecognizer];

Ve içinde, - (void)textFieldDidEndEditing:(UITextField *)textFieldhareket tanıyıcıyı kaldırmanız yeterlidir:

[self.superview.superview removeGestureRecognizer:gestureRecognizer];

Umarım yardımcı olur.


Bu benim için yaptı. Teşekkürler hac.jack
gilsaints88

2

Hücrenin herhangi bir bölümü seçildiğinde hücrenin klavyeyi açmasını ve hücre dışında herhangi bir yere tıklarsanız kapatmasını istedim. Klavyeyi açmak için:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
    if (selected)
    {
        [self.textField becomeFirstResponder];
    }
}

(NOT: Hücreyi alt sınıflara ayırdım, ancak bunu tableView:didSelectRowAtIndexPath:temsilci yönteminde kolayca gerçekleştirebilirsiniz UITableView)

Bunu yapmak, en iyi çözümlerde, hücreye iki kez tıklarsanız klavyenin sallanacağı anlamına geliyordu, ilk olarak hareket tanıyıcı klavyeyi kapatmaya çalıştı ve ikinci olarak hücre yeniden seçildi ve klavyeyi açmaya çalıştı.

Çözüm, tıklamanın seçili hücrenin içinde olup olmadığını kontrol etmektir:

- (void)viewDidLoad
{
    [super viewDidLoad];
    //gesture recognizer to close the keyboard when user taps away
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard:)];
    tap.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tap];
}

-(void)dismissKeyboard:(UIGestureRecognizer*)tapGestureRecognizer
{
    if (!CGRectContainsPoint([self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]].frame, [tapGestureRecognizer locationInView:self.tableView]))
    {
        [self.view endEditing:YES];
    }
}

2

Harika çalışan bir çözüm buldum.

UIGestureRecognizerDelegate yöntemini ve - moveRecognizer: shouldReceiveTouch: yöntemini kullanmak gerekir .

Hareket tanıyıcıyı TableView'e aşağıdaki gibi ekleyin:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
tapGestureRecognizer.cancelsTouchesInView = NO;
tapGestureRecognizer.delegate = self;
[self.suggestedTableView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];

Ardından, UITableViewCell sınıfında gerçekleştirilen dokunuşları reddetmek için shouldReceiveTouch temsilci yöntemini uygulayın. HideKeyboard dokunmatik UITableViewCell sınıfının dışında gerçekleştirilen edildiğinde yöntemi yalnızca çağrılır.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if([touch.view isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    // UITableViewCellContentView => UITableViewCell
    if([touch.view.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    // UITableViewCellContentView => UITableViewCellScrollView => UITableViewCell
    if([touch.view.superview.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    return YES; // handle the touch
}

- (void) hideKeyboard{
    [textField resignFirstResponder];
}

2

UITableViewbackgroundViewSwift'de gösterildiği gibi, hücre seçimiyle uğraşmadan bu davranışı elde ettiğim kullanışlı bir özelliğe sahiptir :

let tableBackTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
tableView.backgroundView = UIView()
tableView.backgroundView?.addGestureRecognizer(tableBackTapRecognizer)


1

Basitçe bir UITapGestureRecognizer kullanarak ve cancelsTouchesInView = NOhücreler ve UITextViews öğesine dokunmanın da gizlemeyi tetiklediği anlamına gelir. Birden fazla UITextView'a sahipseniz ve bir sonrakine dokunursanız bu kötüdür. Klavye gizlenmeye başlayacak ve ardından bir sonraki textView ilk Yanıtlayıcı olacak ve klavye tekrar görünür hale gelecektir. Bundan kaçınmak için, dokunma konumunu kontrol edin ve klavyeyi yalnızca dokunma bir hücrede değilse gizleyin:

// init
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapTableView:)];
tapRecognizer.cancelsTouchesInView = NO;
[self.tableView addGestureRecognizer:tapRecognizer];


// Hide on tap
- (void)didTapTableView:(UITapGestureRecognizer *)tap
{
    CGPoint point = [tap locationInView:tap.view];
    [self.view endEditing:!CGRectContainsPoint([self.tableView rectForRowAtIndexPath:[self.tableView indexPathForRowAtPoint:point]], point)];
}

İçin için scrollViewWillBeginDragging:tetiklenmesi, Tableview en scrollEnabledmülkiyetinde olmalıdırYES

// Hide on scroll
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.view endEditing:YES];
}

Benim için mükemmel. Tablo görünümü hücresine bir metin kutusu eklendi; klavyenin dışından dokunursam kapat
Nicola

0

Neden metin alanlarıyla dolu bir tablo oluşturmak istiyorsunuz? Metin alanlarını içeren her satır için ayrıntılı bir görünüm kullanmalısınız. Ayrıntılı görünümünüzü ittiğinizde, kullanıcının tablo listesinden yalnızca bir tıklama ile düzenlemeye başlayabilmesi için "[myTextField beenFirstResponder]" ı çağırdığınızdan emin olun.


Apple'ın Kişiler uygulaması tam olarak bunu yapıyor. Kendi başına metin alanlarıyla dolu olduğunu söyleyemem , ancak bunları iyi bir etki için kullanıyor.
Joe D'Andrea

2
Bir tablo görünümünde metni satır içinde düzenlemek, kullanıcının düzenlemek istediği her metin alanı için ayrıntılı görünümleri zorlamaktan çok daha hızlı ve sezgiseldir ... En yakın HTML formunu veya iPhone Tercihler bölmelerindeki veya Kişiler uygulamasındaki metin alanlarını sormanız yeterlidir veya vs vs vs ... Apple'ın bunu standart bir hücre tipi yapmamış olması gerçekten utanç verici, ancak web'de bunu başarmakla ilgili çok fazla bilgi var.
glenc

0

Tablo görünümünüzü alt sınıfa ayırmaya istekliyseniz (ugh!), Bunun gibi bir şey işe yarayabilir:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

   BOOL backgroundTouched = YES;

   for (UITouch *touch in touches) {
      CGPoint location = [touch locationInView:self];
      for (UITableViewCell *cell in self.visibleCells) {
         if (CGRectContainsPoint(cell.frame, location)) {
            backgroundTouched = NO;
            break;
         }
      }
   }

   if (backgroundTouched) {
      for (UITableViewCell *cell in self.visibleCells) {
         // This presumes the first subview is the text field you want to resign.
         [[cell.contentView.subviews objectAtIndex:0] resignFirstResponder];
      }
   }

   [super touchesBegan:touches withEvent:event];
}

0

Return tuşuna basılıyken klavyeyi iptal etmek istiyorsanız, aşağıdaki kodu textField'a ekleyebilirsiniz, yani döndürme yöntemi:

- (BOOL)textFieldShouldReturn:(UITextField *)atextField
{
   [textField resignFirstresponder];
}

Bazı metin alanlarının bir seçici görünümü veya bir başkası alt görünüm olarak olabilir, bu durumda yukarıdaki yöntem çalışmaz, bu durumda UITapGestureRecognizer sınıfını kullanmamız gerekir, yani viewDidLoad yöntemine aşağıdaki kod parçacığını eklememiz gerekir örn:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard)];

    [self.view addGestureRecognizer:tap];

Şimdi basitçe istifa yanıtlayıcısını seçici yöntemine ekleyin, yani:

-(void)dismissKeyboard 
{
    [textField resignFirstResponder];
}

Umarım yardımcı olur, teşekkürler :)


0

Birçok ilginç cevap. Bir UITableView senaryosuna en uygun olduğunu düşündüğüm çözüme farklı yaklaşımlar derlemek istiyorum (bu genellikle kullandığımdır): Genelde istediğimiz şey temelde klavyeyi iki senaryoda gizlemektir: Metin UI öğelerinin dışına dokunmak, veya UITableView'da aşağı / yukarı kaydırılırken. İlk senaryo, bir TapGestureRecognizer aracılığıyla ve ikincisi UIScrollViewDelegate scrollViewWillBeginDragging: yöntemiyle kolayca ekleyebiliriz. İlk iş emri, klavyeyi gizleme yöntemi:

   /**
     *  Shortcut for resigning all responders and pull-back the keyboard
     */
    -(void)hideKeyboard
    {
        //this convenience method on UITableView sends a nested message to all subviews, and they resign responders if they have hold of the keyboard
        [self.tableView endEditing:YES];

    }

Bu yöntem, UITableView görünüm hiyerarşisindeki alt görünümlerin herhangi bir textField kullanıcı arabirimini terk eder, bu nedenle her bir öğeyi bağımsız olarak yeniden bırakmaktan daha pratiktir.

Daha sonra, aşağıdakileri içeren bir dış Dokunma hareketiyle işten çıkarmayla ilgileniyoruz:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self setupKeyboardDismissGestures];

}

- (void)setupKeyboardDismissGestures
{

//    Example for a swipe gesture recognizer. it was not set-up since we use scrollViewDelegate for dissmin-on-swiping, but it could be useful to keep in mind for views that do not inherit from UIScrollView
//    UISwipeGestureRecognizer *swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
//    swipeUpGestureRecognizer.cancelsTouchesInView = NO;
//    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
//    [self.tableView addGestureRecognizer:swipeUpGestureRecognizer];

    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
    //this prevents the gestureRecognizer to override other Taps, such as Cell Selection
    tapGestureRecognizer.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tapGestureRecognizer];

}

TapGestureRecognizer.cancelsTouchesInView ayarını HAYIR olarak ayarlamak, jestRecognizer'ın UITableView'ün normal iç işleyişini geçersiz kılmasını önlemektir (örneğin, hücre Seçimi ile karışmaması).

Son olarak, klavyeyi UITableView yukarı / aşağı kaydırırken gizlemeyi işlemek için, UIScrollViewDelegate protokolü scrollViewWillBeginDragging: yöntemini şu şekilde uygulamalıyız:

.h dosyası

@interface MyViewController : UIViewController <UIScrollViewDelegate>

.m dosyası

#pragma mark - UIScrollViewDelegate

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self hideKeyboard];
}

Umut ediyorum bu yardım eder! =)


0

İşte nihayet böyle işler yaptım. Farklı cevaplardan gelen önerileri ve kodları birleştirdim. Özellikler: klavyeyi kapatmak, düzenlerken metin alanlarını klavyenin üzerine taşımak ve "Sonraki" ve "Bitti" klavye dönüş türünü ayarlamak. Daha fazla alanla DEĞİŞTİR "..."

static const CGFloat ANIMATION_DURATION = 0.4;
static const CGFloat LITTLE_SPACE = 5;
CGFloat animatedDistance;
CGSize keyboardSize;

@interface ViewController () <UITextFieldDelegate>
 @property (weak, nonatomic) IBOutlet UITextField *firstNameTXT;
  .....// some other text fields
 @property (weak, nonatomic) IBOutlet UITextField *emailTXT;
@end

@implementation ViewController
- (void)viewDidLoad{
.....
// add tap gesture to help in dismissing keyboard
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(tapScreen:)];// outside textfields

[self.view addGestureRecognizer:tapGesture];

// set text fields return key type to Next, last text field to Done
[self.firstNameTXT setReturnKeyType:UIReturnKeyNext];
.....
[self.emailTXT setReturnKeyType:UIReturnKeyDone];

// set text fields tags
[self.firstNameTXT setTag:0];
....// more text fields
[self.emailTXT setTag:5];

// add keyboard notification
[[NSNotificationCenter defaultCenter] addObserver:self     selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self      selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
}

// dismiss keyboard when tap outside text fields
- (IBAction)tapScreen:(UITapGestureRecognizer *)sender {
  if([self.firstNameTXT isFirstResponder])[self.firstNameTXT resignFirstResponder];
  ...
  if([self.emailTXT isFirstResponder])[self.emailTXT  resignFirstResponder];

  }
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
   if(textField.returnKeyType==UIReturnKeyNext) {
     // find the text field with next tag
     UIView *next = [[textField superview] viewWithTag:textField.tag+1];
     [next becomeFirstResponder];
   } else if (textField.returnKeyType==UIReturnKeyDone || textField.returnKeyType==UIReturnKeyDefault) {
    [textField resignFirstResponder];
 }
return YES;
}

// Moving current text field above keyboard
-(BOOL) textFieldShouldBeginEditing:(UITextField*)textField{
   CGRect viewFrame = self.view.frame;
   CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
   CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
   CGFloat textFieldBottomLine = textFieldRect.origin.y + textFieldRect.size.height + LITTLE_SPACE;//

   CGFloat keyboardHeight = keyboardSize.height;

   BOOL isTextFieldHidden = textFieldBottomLine > (viewRect.size.height - keyboardHeight)? TRUE :FALSE;
  if (isTextFieldHidden) {
    animatedDistance = textFieldBottomLine - (viewRect.size.height - keyboardHeight) ;
    viewFrame.origin.y -= animatedDistance;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
  }
  return YES;
}

-(void) restoreViewFrameOrigionYToZero{
  CGRect viewFrame = self.view.frame;
  if (viewFrame.origin.y != 0) {
    viewFrame.origin.y = 0;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
  }
}

-(void)keyboardDidShow:(NSNotification*)aNotification{
   NSDictionary* info = [aNotification userInfo];
   keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
 }

-(void)keyboardDidHide:(NSNotification*)aNotification{
   [self restoreViewFrameOrigionYToZero];// keyboard is dismissed, restore frame view to its  zero origin
}
@end

0

@ mixca'nın cevabı çok kullanışlı ama ya UITextField'den farklı bir şey varsa. Yinelemeli işlevle ana görünümün tüm alt görünümlerini arayarak bunu halletmenin en iyi yolunu düşünüyorum, aşağıdaki örneğe bakın

- (BOOL)findAndResignFirstResponder {
if (self.isFirstResponder) {
    [self resignFirstResponder];
    return YES;
}

    for (UIView *subView in self.subviews) {
        if ([subView findAndResignFirstResponder]) {
            return YES;
        }
    }
    return NO;
}

ve ayrıca bu yöntemi yardımcı sınıfınıza ekleyebilir ve @ mixca'nın yanıtı gibi dokunma hareketlerinden kullanabilirsiniz ..


0

Hızlı 4 / 4.2 / 5

Başka bir şey yapmadan önce, bir hücreye dokunulduğunda klavyeyi de kapatabilirsiniz.

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    view.endEditing(true)
    // Do something here
    }

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.