web-dev-qa-db-ja.com

(Swiftの)UITextFieldの外のどこかに触れたときにキーボードを閉じる方法は?

私はUIViewControllerを持つプロジェクトに取り組んでいます。ViewControllerには、scrollviewにUIScrollViewとUITextFieldがあります。このような: - テキストフィールドにテキストを入力した後、キーボードを閉じて非表示にし、テキストフィールド以外の場所をタップしようとしています。私は次のコードを試しました:

override func viewDidLoad() {
    super.viewDidLoad()
    self.textField.delegate = self;
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    self.view.endEditing(true)
}

Scrollviewの外側をタップすると機能しますが、scrollviewをタップしても何も起こらず、キーボードは非表示になりません。

テキストフィールドの外でanywhereをタップしたときにキーボードを閉じる方法はありますか?ありがとう

57
White Hat

Swift 4用に編集

編集:@objcを追加しました。これはパフォーマンスにとって最良のオプションではありませんが、ここでの1つのインスタンスは、より良い解決策が見つかるまで、あまり多くの問題を引き起こさないはずです。

GestureRecognizerの背後にあるアイテムを操作する必要がある場合に修正するために編集されました。

編集:これを指摘してくれて@Raoに感謝します。 tap.cancelsTouchesInView = falseを追加しました。

これは、複数のUITextViewまたはUITextFieldを持つのに役立ちます。

View Controllerの拡張機能を作成します。これは、.resignFirstResponder()を使用しようとするよりもはるかにスムーズで、手間もかかりません。

extension UIViewController
{
    func setupToHideKeyboardOnTapOnView()
    {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(
            target: self,
            action: #selector(UIViewController.dismissKeyboard))

        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard()
    {
        view.endEditing(true)
    }
}

ViewDidLoadでself.setupToHideKeyboardOnTapOnView()を呼び出します

103

これを試してください、それはテスト済みで動作しています:

For Swift 3.0/4.

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    self.view.endEditing(true)
}

古いSwiftの場合

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
    self.view.endEditing(true)
}
56
iAnurag

スイフト3

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
}
16
Giang

この場合、選択肢の1つとしてUITapGestureがあります。念のため、サンプルコードを作成しようとしました。このような、

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()
    }
}
13
pixyzehn

ScrollViewで動作するSwift 3の作業ソリューション

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()
    }
}

別の 質問 は、私が参照して使用したこの問題について述べています。受け入れられた回答はSwift 3では機能しなくなりました。現在選択されている回答は以下の回答になります。

11
Devbot10

詳細

  • Xcode 10.2.1(10E1001)、Swift 5

解決策1

endEditing(_:)

let gesture = UITapGestureRecognizer(target: tableView, action: #selector(UITextView.endEditing(_:)))
tableView.addGestureRecognizer(gesture)

ソリューションの使用法1.完全なサンプル

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"
        textField.becomeFirstResponder()
        view.addSubview(textField)
        let gesture = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:)))
        view.addGestureRecognizer(gesture)
    }
}

解決策2

クラスTapGestureRecognizer

import UIKit

class TapGestureRecognizer: UITapGestureRecognizer {

    let identifier: String

    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
    }
}

拡張UIView

import UIKit

extension UIView {

    private var hideKeybordOnTapIdentifier: String { return "hideKeybordOnTapIdentifier" }

    private var hideKeybordOnTapGestureRecognizer: TapGestureRecognizer? {
        let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(UIView.hideKeyboard),
                                                       identifier: hideKeybordOnTapIdentifier)
        if let gestureRecognizers = self.gestureRecognizers {
            for gestureRecognizer in gestureRecognizers {
                if let tapGestureRecognizer = gestureRecognizer as? TapGestureRecognizer,
                    tapGestureRecognizer == hideKeyboardGesture {
                    return tapGestureRecognizer
                }
            }
        }
        return nil
    }

    @objc private func hideKeyboard() { endEditing(true) }

    var hideKeyboardOnTap: Bool {
        set {
            let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(hideKeyboard),
                                                           identifier: hideKeybordOnTapIdentifier)
            if let hideKeybordOnTapGestureRecognizer = hideKeybordOnTapGestureRecognizer {
                removeGestureRecognizer(hideKeybordOnTapGestureRecognizer)
                if gestureRecognizers?.count == 0 { gestureRecognizers = nil }
            }
            if newValue { addGestureRecognizer(hideKeyboardGesture) }
        }
        get { return hideKeybordOnTapGestureRecognizer == nil ? false : true }
    }
}

ソリューション2の使用

view.hideKeyboardOnTap = true

ソリューション2の完全なサンプル

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"
        textField.becomeFirstResponder()
        view.addSubview(textField)
        view.hideKeyboardOnTap = true
    }
}
5

これをチェックしてください。

override func viewDidLoad() {
    var tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap))
    self.view.userInteractionEnabled = true
    self.view.addGestureRecognizer(tapGesture)
}

次に、タップハンドラーがあります。

  func handleTap(sender: UITapGestureRecognizer) {
    self.view.endEditing(true)
}
5
handiansom

Swift 3の場合

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    self.view.endEditing(true)
}
3
Davina Arnold

これは、任意の数の入力項目の入力領域の外側をタッチしたときに機能します。

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)
    }
2
Venkat Ram

テキストフィールドと異なるすべてのタッチは、キーボードを閉じるか、resignfirstresponderを使用します

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
 UITouch *touch = [touches anyObject];
 if(![touch.view isMemberOfClass:[UITextField class]]) {
     [touch.view endEditing:YES];
 }
}
1
Miguel Monteiro

私は同じ問題を抱えていて、ついに解決しました!

ストーリーボードでTapGestureRecognizerを設定し、ViewControllerでアウトレットを設定します

@IBOutlet var tapGesture: UITapGestureRecognizer!

次に、ViewControllerでIBActionを設定します

@IBAction func DismissKeyboard(sender: UITapGestureRecognizer)
{
 self.view.endEditing(true)
} 

これらの行をviewDidLoadメソッドに追加します

override func viewDidLoad()
{
    super.viewDidLoad()
    self.view.addGestureRecognizer(tapGesture)
}

そしてそれは動作するはずです

それが役立つことを願っています!

1
Lynkz7
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
}
1
Subhajit

[キーボードの種類]に移動し、[デフォルト]またはTextFieldが必要なものを選択します。その後、メソッドをオーバーライドして、通常はtouchingBeginsという名前を付けます。以下は追加を忘れたものです

super.touchingBegins(touches, withEvent: event)
 }
0
Katz

ユーザーが現在入力している場所に関係なくキーボードを隠すこのメソッドをObj-Cで作成しました。

//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];
    }
}

それがSwiftに翻訳可能であり、意味があることを願っています。アプリケーション内のどこからでも呼び出すことができ、VCが何であっても、キーボードを非表示にします。

0
AlexKoren

タップジェスチャ認識機能を導入し、その設定とアクションを実行します。

コードを使用します。

nameofyourtextfield。resignfirstresponder()

0
kuni

Swift4で

 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            self.view.endEditing(true)
        }
0
Raghib Arshi

// Swiftで4 ..うまくいきました。

func setupKeyboardDismissRecognizer(){
    let tapRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(searchingActivity.dismissKeyboard))

    self.view.addGestureRecognizer(tapRecognizer)
}

    @objc func dismissKeyboard()
    {
        view.endEditing(true)
        searchTableView.isHidden = true
    }

// viewDidLoadでこの関数をsetupKeyboardDismissRecognizer()呼び出します

0
Raghib Arshi