私はセルとしてsをUITableView
持っています。背景に触れUITextField
たらキーボードを閉じたいのですが。のサイズを作成し、それをの後ろに配置することでUITableView
、これを実行しようとしています。唯一の問題は、タッチがUITableViewにある場合でも、すべてのタッチをキャッチすることです。私は何が間違っているのですか?UIButton
UITableView
UITableView
UIButton
ありがとう!
私はセルとしてsをUITableView
持っています。背景に触れUITextField
たらキーボードを閉じたいのですが。のサイズを作成し、それをの後ろに配置することでUITableView
、これを実行しようとしています。唯一の問題は、タッチがUITableViewにある場合でも、すべてのタッチをキャッチすることです。私は何が間違っているのですか?UIButton
UITableView
UITableView
UIButton
ありがとう!
これは、UITapGestureRecognizerオブジェクトを作成し (デフォルトでは、シングル タップで「ジェスチャー」を検出するため、それ以上のカスタマイズは必要ありません)、ジェスチャーが起動されたときのターゲット/アクションを指定し、ジェスチャー認識オブジェクトをアタッチすることで簡単に実行できます。あなたのテーブルビューに。
たとえば、おそらくあなたのviewDidLoad
方法で:
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];
メソッドは次のようになりhideKeyboard
ます。
- (void) hideKeyboard {
[textField1 resignFirstResponder];
[textField2 resignFirstResponder];
...
...
}
UITextField
オブジェクトの内側に触れた場合、ジェスチャは発生しないことに注意してください。バックUITableView
グラウンド、フッタービュー、ヘッダービュー、UILabels
セル内などで発生します。
次のように設定すると、UITapGestureRecognizer ソリューションはテーブル セルの選択で機能します。
gestureRecognizer.cancelsTouchesInView = NO;
これを行う最良の方法は次のとおりです。これをするだけ
[self.view endEditing:YES];
また
[[self.tableView superView] endEditing:YES];
まず、次を追加してscrollViewWillBeginDragging
in yourでリッスンします。UIViewController
UIScrollViewDelegate
.h ファイル内:
@interface MyViewController : UIViewController <UIScrollViewDelegate>
.m ファイル内:
- (void)scrollViewWillBeginDragging:(UIScrollView *)activeScrollView {
[self dismissKeyboard];
}
次に、他の相互作用をリッスンします。
- (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];
}
次に実装しますdismissKeyboard
:
- (void)dismissKeyboard {
NSLog(@"dismissKeyboard");
[yourTextFieldPointer resignFirstResponder];
}
また、私のように、カスタム テーブル セル内の UITextField のキーボードを閉じたい場合は、次のようにします。
- (void)dismissKeyboard {
NSLog(@"dismissKeyboard");
CustomCellClass *customCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[customCell.textFieldInCell resignFirstResponder];
}
探している方の参考になれば幸いです!!
tableView.keyboardDismissMode = .onDrag
コーディングを楽しむための迅速なバージョンは次のとおりです。
タップ ジェスチャ認識機能を追加してから、キーボードを閉じます。TextField のアウトレットは必要ありません。
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
}
私はこのようにしました:
TableViewController にメソッドを作成して、ファーストレスポンダーを非アクティブ化します (その時点で TextBox になります)。
- (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;
}
tableView:didSelectRowAtIndexPath:
前のメソッドを呼び出します。
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
...
[self findAndResignFirstResonder: self.view];
...
}
@interface DismissableUITableView : UITableView {
}
@end
@implementation DismissableUITableView
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.superview endEditing:YES];
[super touchesBegan:touches withEvent:event];
}
@end
次に、NibファイルでUITableViewのタイプをDismissableUITableViewに設定していることを確認してください.....このクラスのより良い名前を考えたかもしれませんが、要点はわかります。
iOS7 をターゲットにしている場合は、次のいずれかを使用できます。
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
前者はテーブルビューがスクロールされたときにキーボードを画面外にアニメートし、後者はストックメッセージアプリのようにキーボードを非表示にします.
これらは fromUIScrollView
であり、 from をUITableView
継承していることに注意してください。
これを試して:
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)
}
うまく機能するソリューションを見つけました。
UIGestureRecognizerDelegateとメソッドを使用するために必要です– ジェスチャRecognizer:shouldReceiveTouch:。
次のように、ジェスチャ認識機能を TableView に追加します。
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
tapGestureRecognizer.cancelsTouchesInView = NO;
tapGestureRecognizer.delegate = self;
[self.suggestedTableView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];
次に、UITableViewCell クラスで実行されるタッチを拒否するshouldReceiveTouchデリゲート メソッドを実装します。hideKeyboardメソッドは、タッチが UITableViewCell クラス外で実行された場合にのみ呼び出されます。
- (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];
}
私は同じ問題を抱えていましたが、これが私の解決策です。それは私にとって完璧に機能します:
実装したビューまたはビュー コントローラーで<UITextFieldDelegate>
(私の場合、UITableViewCell
TextFieldCell というカスタムがあります)、
UITapGestureRecognizer
をプロパティとして宣言します。
@interface TextFieldCell : UITableViewCell <UITextFieldDelegate>
{
UITextField *theTextField;
UITapGestureRecognizer *gestureRecognizer;
}
@property (nonatomic,retain) UITextField *theTextField;
@property (nonatomic,retain) UITapGestureRecognizer *gestureRecognizer;
ビュー/コントローラーで初期化します。
self.gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyboard:)];
- (void)textFieldDidBeginEditing:(UITextField *)textField
メソッドでは、を使用しsuperView
て tableView に移動し、次を呼び出しますaddGestureRecognizer
。
[self.superview.superview addGestureRecognizer:gestureRecognizer];
で- (void)textFieldDidEndEditing:(UITextField *)textField
、ジェスチャ レコグナイザーを削除します。
[self.superview.superview removeGestureRecognizer:gestureRecognizer];
それが役に立てば幸い。
セルの任意の部分が選択されたときにセルがキーボードを開き、セルのどこかをクリックするとキーボードを閉じるようにしたかったのです。キーボードを開くには:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if (selected)
{
[self.textField becomeFirstResponder];
}
}
tableView:didSelectRowAtIndexPath:
(注: セルをサブクラス化しましたが、のデリゲート メソッドで簡単に実現できますUITableView
)
これを行うと、上位のソリューションでセルを 2 回クリックするとキーボードが揺れ、最初にジェスチャ認識機能がキーボードを閉じようとし、次にセルが再選択されてキーボードが開かれることを意味しました。
解決策は、現在選択されているセル内でクリックが発生したかどうかを確認することです。
- (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];
}
}
UITableView は UIScrollView のサブクラスです。
私が行った方法は、ユーザーによるスクロールイベントをリッスンしてから、resignFirstResponder でした。コードに実装する UIScrollViewDelegate メソッドを次に示します。
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
この種の問題に取り組むとき、私が見つけた最善の方法は、各オブジェクトのデリゲート プロトコルと親クラスのデリゲート プロトコルを調査することです (この場合は UITableViewDelegate、UIScrollViewDelegate です。NS オブジェクトが発生するイベントの数は非常に多く、包括的です。また、プロトコルを実装してから何かをサブクラス化するのも簡単です。
私は解決策を探していましたが、自分のコードに合うものが見つからなかったので、次のようにしました:
http://82517.tumblr.com/post/13189719252/dismiss-keyboard-on-uitableview-non-cell-tap
基本的には前述のアプローチの組み合わせですが、何かをサブクラス化したり、背景ボタンを作成したりする必要はありません。
テーブルビューをサブクラス化する(うーん!)場合は、次のように機能する可能性があります。
- (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];
}
リターンキーが押されている間にキーボードを閉じたい場合は、textFieldに次のコードを追加するだけでメソッドを返すことができます。
- (BOOL)textFieldShouldReturn:(UITextField *)atextField
{
[textField resignFirstresponder];
}
一部のテキストフィールドには、サブビューとしてピッカービューまたはその他のビューがある場合があるため、その場合、上記のメソッドは機能しません。その場合、UITapGestureRecognizerクラスを使用する必要があります。つまり、次のコードスニペットをviewDidLoadメソッドに追加します。
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
ここで、resignレスポンダーをselectorメソッドに追加するだけです。
-(void)dismissKeyboard
{
[textField resignFirstResponder];
}
お役に立てば幸いです、ありがとう:)
テキストフィールドでいっぱいのテーブルを作成したいのはなぜですか? テキスト フィールドを含む行ごとに詳細ビューを使用する必要があります。詳細ビューをプッシュするときは、必ず「[myTextField becomeFirstResponder]」を呼び出して、ユーザーがテーブル リストからワンクリックで編集を開始できるようにします。