Czy jest jakiś sposób, aby zapytać widok iOS, które z jego dzieci ma status pierwszej odpowiedzi? [duplikat]

To pytanie ma już odpowiedź tutaj:

W Mac OS X możesz znaleźć pierwszą odpowiedź w następujący sposób:

[[self window] firstResponder]
Czy da się to jakoś zrobić w iOS? A może musisz wyliczyć kontrolki potomne i wysłać wiadomość isFirstResponder do każdego z nich?
Author: Tommy Herbert, 2011-02-17

4 answers

Trzeba by iterację nad wszystkimi kontrolkami potomnymi i przetestować Właściwość isFirstResponder. Kiedy napotkasz TRUE, WYJDŹ z pętli.

UIView *firstResponder;
for (UIView *view in self.view.subviews) //: caused error
{
    if (view.isFirstResponder)
    {
        firstResponder = view;
        break;
    }
}

LEPSZE ROZWIĄZANIE

Zobacz odpowiedź Jakuba.

 11
Author: Evan Mulawski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:20

Bardzo mi się podoba rozwiązanie VJK , ale jak sugeruje MattDiPasquale, wydaje się bardziej złożone niż to konieczne. Więc napisałem tę prostszą wersję:

Objective-C

#import "UIResponder+FirstResponder.h"

static __weak id currentFirstResponder;

@implementation UIResponder (FirstResponder)

+(id)currentFirstResponder {
    currentFirstResponder = nil;
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:nil forEvent:nil];
    return currentFirstResponder;
}

-(void)findFirstResponder:(id)sender {
   currentFirstResponder = self;
}

@end

Swift 4

import UIKit

extension UIResponder {

    private static weak var _currentFirstResponder: UIResponder?

    static var currentFirstResponder: UIResponder? {
        _currentFirstResponder = nil
        UIApplication.shared.sendAction(#selector(UIResponder.findFirstResponder(_:)), to: nil, from: nil, for: nil)

        return _currentFirstResponder
    }

    @objc func findFirstResponder(_ sender: Any) {
        UIResponder._currentFirstResponder = self
    }
}

Uczyniłem to również metodą klasową, ponieważ wydawało się to mieć więcej sensu. Możesz teraz znaleźć pierwszą odpowiedź w następujący sposób: [UIResponder currentFirstResponder]


 220
Author: Jakob Egger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-06 07:36:52

Napisałem kategorię na UIResponder aby znaleźć pierwszą odpowiedź

@interface UIResponder (firstResponder)
- (id) currentFirstResponder;
@end

I

#import <objc/runtime.h>
#import "UIResponder+firstResponder.h"

static char const * const aKey = "first";

@implementation UIResponder (firstResponder)

- (id) currentFirstResponder {
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:self forEvent:nil];
    id obj = objc_getAssociatedObject (self, aKey);
    objc_setAssociatedObject (self, aKey, nil, OBJC_ASSOCIATION_ASSIGN);
    return obj;
}

- (void) setCurrentFirstResponder:(id) aResponder {
    objc_setAssociatedObject (self, aKey, aResponder, OBJC_ASSOCIATION_ASSIGN);
}

- (void) findFirstResponder:(id) sender {
    [sender setCurrentFirstResponder:self];
}

@end

Wtedy w dowolnej klasie, która wywodzi się z UIResponder możesz uzyskać pierwszą odpowiedź, dzwoniąc

UIResponder* aFirstResponder = [self currentFirstResponder];

Ale pamiętaj, aby najpierw zaimportować plik interfejsu kategorii UIResponder!

Wykorzystuje udokumentowane API, więc nie powinno być problemów z odrzuceniem App store.

 25
Author: VJK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-30 18:53:55

Jeśli potrzebujesz pierwszej pomocy tylko po to, aby poprosić go o rezygnację ze statusu, oto podejście, aby każdy zrezygnował. UIView ma metodę, która będzie powtarzała wszystkie podglądy UIView i poprosi wszystkich, którzy są pierwszymi odpowiedziami, aby zrezygnowali.

[[self view] endEditing:YES];

Oto link do dokumentów UIView firmy Apple "Ta metoda patrzy na bieżący widok i jego hierarchię podkategorii dla pola tekstowego, które jest obecnie pierwszym odpowiedzialnym. Jeśli go znajdzie, prosi to pole tekstowe o rezygnację jako pierwsze / align = "left" / Jeśli parametr force jest ustawiony na YES, pole tekstowe nigdy nie jest nawet pytane; jest ono zmuszone do rezygnacji."

 11
Author: Praxiteles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-27 03:28:21