Jak odrzucić klawiaturę, gdy dotykasz gdziekolwiek poza UITextField (w języku swift)?
Pracuję nad projektem, który ma UIViewController, na kontrolerze widoku znajduje się UIScrollView i UITextField na scrollview. w ten sposób: Próbuję odrzucić klawiaturę i ukryć ją po wpisaniu tekstu w polu tekstowym i stuknąć w dowolnym miejscu poza pole tekstowe. Wypróbowałem następujący kod:
override func viewDidLoad() {
super.viewDidLoad()
self.textField.delegate = self;
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
Działa u mnie, gdy stukam poza przewijaniem, ale kiedy stukam w przewijanie, nic się nie dzieje, a klawiatura nie ukrywa.
Jest czy jest jakiś sposób na oddalenie klawiatury przy stukaniu gdziekolwiek poza pole tekstowe? dzięki
15 answers
Edited for Swift 4
Edit: Added @objc
. Chociaż nie jest to najlepsza opcja dla wydajności, jedna jej instancja nie powinna powodować zbyt wielu problemów, dopóki nie pojawi się lepsze rozwiązanie.
Edytowano, aby naprawić, gdy trzeba wchodzić w interakcje z elementami za GestureRecognizer.
Edit: dzięki @Rao za wskazanie tego. Dodano tap.cancelsTouchesInView = false
.
To powinno pomóc w posiadaniu wielu UITextView
lub UITextField
Tworzenie rozszerzenia widoku kontroler. To działa znacznie płynniej dla mnie i z mniejszym kłopotem niż próba użycia .resignFirstResponder()
extension UIViewController
{
func hideKeyboard()
{
let tap: UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: #selector(UIViewController.dismissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
@objc func dismissKeyboard()
{
view.endEditing(true)
}
}
Wywołanie self.hideKeyboard()
w viewDidLoad
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-09-04 17:24:35
Spróbuj tego, jest przetestowany i działa:
Dla Swift 3.0 / 4.0
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
Dla Starszych Swift
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
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-07-21 10:53:07
W tym przypadku, istnieje UITapGesture jako jeden z wyborów. Próbowałem stworzyć przykładowy kod na wszelki wypadek. Jak to,
class ViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let tapGesture = UITapGestureRecognizer(target: self, action: "tap:")
view.addGestureRecognizer(tapGesture)
}
func tap(gesture: UITapGestureRecognizer) {
textField.resignFirstResponder()
}
}
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
2015-08-29 01:34:06
Rozwiązanie robocze dla Swift 3, które współpracuje z ScrollView
class ViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// The next line is the crucial part
// The action is where Swift 3 varies from previous versions
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tap(gesture:)))
self.view.addGestureRecognizer(tapGesture)
}
func tap(gesture: UITapGestureRecognizer) {
textField.resignFirstResponder()
}
}
Kolejne pytanie mówiące o tej kwestii, do której się odwołałem i której użyłem. Zaakceptowana odpowiedź nie działa już w Swift 3. Aktualnie wybraną odpowiedzią powinna być odpowiedź poniżej.
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:34:45
Swift 3
override func viewDidLoad() {
super.viewDidLoad()
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
}
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-13 04:53:52
Szczegóły
XCode 8.2.1, Swift 3
Zadanie
Ustaw UITapGestureRecognizer dla widoku UIViewController, który zamknie klawiaturę i uczyni tę funkcję właściwością bool UIView.
Złożona implementacja, ale użycie jest w jednej linii
Class TapGestureRecognizer
import UIKit
class TapGestureRecognizer: UITapGestureRecognizer {
let identifier: String
private override init(target: Any?, action: Selector?) {
self.identifier = ""
super.init(target: target, action: action)
}
init(target: Any?, action: Selector?, identifier: String) {
self.identifier = identifier
super.init(target: target, action: action)
}
static func == (left: TapGestureRecognizer, right: TapGestureRecognizer) -> Bool {
return left.identifier == right.identifier
}
}
Rozszerzenie UIView
import UIKit
extension UIView {
private var disableKeybordWhenTappedGestureRecognizerIdentifier:String {
return "disableKeybordWhenTapped"
}
private var disableKeybordWhenTappedGestureRecognizer: TapGestureRecognizer? {
let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(UIView.hideKeyboard), identifier: disableKeybordWhenTappedGestureRecognizerIdentifier)
if let gestureRecognizers = self.gestureRecognizers {
for gestureRecognizer in gestureRecognizers {
if let tapGestureRecognizer = gestureRecognizer as? TapGestureRecognizer, tapGestureRecognizer == hideKeyboardGesture, tapGestureRecognizer == hideKeyboardGesture {
return tapGestureRecognizer
}
}
}
return nil
}
@objc private func hideKeyboard() {
endEditing(true)
}
var disableKeybordWhenTapped: Bool {
set {
let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(UIView.hideKeyboard), identifier: disableKeybordWhenTappedGestureRecognizerIdentifier)
if let disableKeybordWhenTappedGestureRecognizer = self.disableKeybordWhenTappedGestureRecognizer {
removeGestureRecognizer(disableKeybordWhenTappedGestureRecognizer)
if gestureRecognizers?.count == 0 {
gestureRecognizers = nil
}
}
if newValue {
addGestureRecognizer(hideKeyboardGesture)
}
}
get {
return disableKeybordWhenTappedGestureRecognizer == nil ? false : true
}
}
}
Użycie
view.disableKeybordWhenTapped = true
Pełna Próbka
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let textField = UITextField(frame: CGRect(x: 50, y: 50, width: 200, height: 30))
textField.borderStyle = .roundedRect
textField.placeholder = "Enter text"
view.addSubview(textField)
view.disableKeybordWhenTapped = true
}
}
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-02-12 11:58:57
Zobacz też
override func viewDidLoad() {
var tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap))
self.view.userInteractionEnabled = true
self.view.addGestureRecognizer(tapGesture)
}
Wtedy twój uchwyt jest.
func handleTap(sender: UITapGestureRecognizer) {
self.view.endEditing(true)
}
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-04-27 02:41:51
Działa po dotknięciu poza obszarem wejściowym dla dowolnej liczby elementów wejściowych.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
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
2016-08-19 10:47:27
Dla Swift 3
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
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-08-07 03:45:09
Miałem ten sam problem i w końcu go rozwiązałem !
Ustaw TapGestureRecognizer w Storyboardzie, a następnie wylot w kontrolerze ViewController
@IBOutlet var tapGesture: UITapGestureRecognizer!
Następnie Ustaw IBAction w kontrolerze ViewController
@IBAction func DismissKeyboard(sender: UITapGestureRecognizer)
{
self.view.endEditing(true)
}
Dodaj te linie do metody viewDidLoad
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addGestureRecognizer(tapGesture)
}
I powinno działać
Mam nadzieję, że to pomoże !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
2015-10-27 16:10:54
Każde dotknięcie pola tekstowego Wyłącz klawiaturę lub użyj resignfirstresponder
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if(![touch.view isMemberOfClass:[UITextField class]]) {
[touch.view endEditing:YES];
}
}
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
2016-08-04 18:39:25
func findAndResignFirstResponder(_ stView: UIView) -> Bool {
if stView.isFirstResponder {
stView.resignFirstResponder()
return true
}
for subView: UIView in stView.subviews {
if findAndResignFirstResponder(subView) {
return true
}
}
return false
}
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-27 18:49:40
Stworzyłem tę metodę w Obj-C, która ukrywa klawiaturę bez względu na to, gdzie użytkownik aktualnie pisze:
//call this method
+ (void)hideKeyboard {
//grab the main window of the application
UIWindow *window = [UIApplication sharedApplication].keyWindow;
//call our recursive method below
[self resignResponderForView:window];
}
//our recursive method
+ (void)resignResponderForView:(UIView *)view {
//resign responder from this view
//If it has the keyboard, then it will hide the keyboard
[view resignFirstResponder];
//if it has no subviews, then return back up the stack
if (view.subviews.count == 0)
return;
//go through all of its subviews
for (UIView *subview in view.subviews) {
//recursively call the method on those subviews
[self resignResponderForView:subview];
}
}
Mam nadzieję, że to przełoży się na Swift i ma sens. Może być wywołany w dowolnym miejscu w aplikacji i ukryje klawiaturę bez względu na to, na jakim VC jesteś lub cokolwiek.
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
2015-08-29 03:00:30
Przejdź do klawiatury Type i wybierz Default lub whatever you need the TextField for. Następnie zastąp metodę nazywaj ją jak chcesz, Zwykle nazywam ją touchingBegins. Poniżej jest to, czego zapomniałeś dodać
super.touchingBegins(touches, withEvent: event)
}
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
2015-08-29 03:19:13
Wprowadź rozpoznawacz gestów stukania i ustaw go i uruchom.
Użyj kodu:
nameofyourtextfield .resignfirstresponder ()
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
2016-08-19 10:59:37