225

キーボードが表示されたときにテキストフィールドを上にスクロールする独自の関数を作成しました。テキストフィールドをタップしてキーボードを閉じるために、タップしたUITapGestureRecognizerときにテキストフィールドのファーストレスポンダーを辞任する処理を行うを作成しました。

これで、テキストフィールドのオートコンプリートも作成しました。これはUITableView、テキストフィールドのすぐ下に作成され、ユーザーがテキストを入力するとアイテムが入力されます。

ただし、自動完了テーブルのエントリの1つを選択すると、didSelectRowAtIndexPathは呼び出されません。代わりに、タップジェスチャレコグナイザーが呼び出され、ファーストレスポンダーを辞任したようです。

タップジェスチャレコグナイザーにタップメッセージをに渡し続けるように指示する方法があるUITableViewと思いますが、それが何であるかわかりません。どんな助けでも大歓迎です。

4

21 に答える 21

276

わかりました、ジェスチャ認識機能のドキュメントを検索した後、ようやく見つけました。

UIGestureRecognizerDelegate解決策は、以下を実装して追加することでした。

#pragma mark UIGestureRecognizerDelegate methods
    
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
  if ([touch.view isDescendantOfView:autocompleteTableView]) {
            
    // Don't let selections of auto-complete entries fire the 
    // gesture recognizer
    return NO;
  }
        
  return YES;
}

それはそれの世話をしました。うまくいけば、これは他の人にも役立ちます。

于 2011-11-20T00:30:58.983 に答える
227

この問題を解決する最も簡単な方法は次のとおりです。

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

これにより、UIGestureRecognizerはタップを認識し、タッチを次のレスポンダーに渡します。このメソッドの意図しない結果は、UITableViewCell別のビュー コントローラーをプッシュする画面がある場合です。ユーザーが行をタップしてキーボードを閉じると、キーボードとプッシュの両方が認識されます。これがあなたの意図とは思えませんが、この方法は多くの状況に適しています。

また、Robert の回答を拡張して、問題のテーブルビューへのポインターがある場合は、文字列に変換する代わりにそのクラスを直接比較して、Apple が命名法を変更しないことを願っています。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
     shouldReceiveTouch:(UITouch *)touch
{
    if([touch.view class] == tableview.class){
        return //YES/NO
    }

    return //YES/NO

}

UIGestureRecognizerこのコードを含むデリゲートを含めるには、 も宣言する必要があることに注意してください。

于 2012-10-12T03:28:23.463 に答える
83

cancelsTouchesInView認識機能を false に設定します。それ以外の場合は、それ自体でタッチを「消費」し、それをテーブル ビューに渡しません。そのため、選択イベントは発生しません。

たとえばswift

let tapOnScreen: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "CheckTheTime")
tapOnScreen.cancelsTouchesInView = false
view.addGestureRecognizer(tapOnScreen)
于 2016-03-22T09:39:37.643 に答える
28

テーブルビューにタップジェスチャを追加し、同時にセルを選択できるようにするためのより良い解決策があるかもしれません:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    if gestureRecognizer is UITapGestureRecognizer {
        let location = touch.locationInView(tableView)
        return (tableView.indexPathForRowAtPoint(location) == nil)
    }
    return true
}

ユーザーがタップしている画面のポイントでセルを探すだけです。インデックス パスが見つからない場合は、ジェスチャにタッチを受信させます。それ以外の場合はキャンセルします。私にとってはうまくいきます。

于 2014-11-28T10:46:11.263 に答える
14

同様の解決策はgestureRecognizer:shouldReceiveTouch:、ビューのクラスを使用して実装し、実行するアクションを決定することです。このアプローチには、テーブルを直接囲む領域のタップをマスクしないという利点があります(これらの領域のビューは、UITableViewインスタンスから派生しますが、セルを表しません)。

これには、(余分なコードを追加せずに)単一のビューで複数のテーブルを処理できるという利点もあります。

警告:Appleはクラス名を変更しないという前提があります。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    return ![NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"];
}
于 2012-08-13T16:48:35.933 に答える
6

ユーザーがテーブル ビューの外側をタップした場合にのみ、タッチ ジェスチャ機能を呼び出すという別の状況がありました。ユーザーがテーブル ビュー内をタップした場合、タッチ ジェスチャ関数は呼び出されません。さらに、タッチ ジェスチャ関数が呼び出された場合でも、タッチ イベントを消費するのではなく、タップされたビューに渡す必要があります。

結果のコードは、Abdulrahman Masoud の回答と Nikolaj Nielsen の回答を組み合わせたものです。

extension MyViewController: UIGestureRecognizerDelegate {
    func addGestureRecognizer() {
        let tapOnScreen = UITapGestureRecognizer(target: self,
                                                action: #selector(functionToCallWhenUserTapsOutsideOfTableView))

        // stop the gesture recognizer from "consuming" the touch event, 
        // so that the touch event can reach other buttons on view.
        tapOnScreen.cancelsTouchesInView = false

        tapOnScreen.delegate = self

        self.view.addGestureRecognizer(tapOnScreen)
    }

    // if your tap event is on the menu, don't run the touch event.
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if touch.view?.isDescendant(of: self.tableView) == true {
            return false
        }
        return true
    }

    @objc func functionToCallWhenUserTapsOutsideOfTableView() {

        print("user tapped outside table view")
    }
}

そして、MyViewControllerクラスでは、 を持っているクラスで、UITableViewonViewDidLoad()呼び出すようにしましたaddGestureRecognizer():

class MyViewController: UIViewController {
    ...
    override func viewDidLoad() {
        super.viewDidLoad()
        ...
        self.addGestureRecognizer()
        ...
    }
    ...
}
于 2018-11-12T20:48:16.973 に答える
0

これが私の解決策です。これは、認識エンジンの shouldReceiveTouch をキーボードが表示されているかどうかに直接結び付けます。

タップ ジェスチャ認識デリゲートで:

#pragma mark - UIGestureRecognizerDelegate

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if ([PFXKeyboardStateListener sharedInstance].visible) {
        return YES;
    }

    return NO;
}

そしてPFXKeyboardStateListener.h

@interface PFXKeyboardStateListener : NSObject
{
    BOOL _isVisible;
}

+ (PFXKeyboardStateListener *)sharedInstance;

@property (nonatomic, readonly, getter=isVisible) BOOL visible;

@end

そしてPFXKeyboardStateListener.m

static PFXKeyboardStateListener *sharedInstance;

@implementation PFXKeyboardStateListener

+ (PFXKeyboardStateListener *)sharedInstance
{
    return sharedInstance;
}

+ (void)load
{
    @autoreleasepool {
        sharedInstance = [[self alloc] init];
    }
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (BOOL)isVisible
{
    return _isVisible;
}

- (void)didShow
{
    _isVisible = YES;
}

- (void)didHide
{
    _isVisible = NO;
}

- (id)init
{
    if ((self = [super init])) {
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        [center addObserver:self selector:@selector(didShow) name:UIKeyboardDidShowNotification object:nil];
        [center addObserver:self selector:@selector(didHide) name:UIKeyboardWillHideNotification object:nil];
    }
    return self;
}

@end

キーボード リスナーのシングルトン パターンを更新する必要があるかもしれませんが、まだ行っていません。これが私だけでなく、他のすべての人にとってもうまくいくことを願っています。^^

于 2014-03-23T17:12:01.787 に答える
0

私のケースは、self.viewのuisearchbarとuitableviewを含めて異なっていました。ビューに触れて uisearchbar キーボードを閉じたかったのです。

var tapGestureRecognizer:UITapGestureRecognizer?

override func viewWillAppear(animated: Bool) {
    tapGestureRecognizer = UITapGestureRecognizer(target: self, action:Selector("handleTap:"))
}

UISearchBar デリゲート メソッドで:

func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool {
    view.addGestureRecognizer(tapGestureRecognizer!)
    return true
}
func searchBarShouldEndEditing(searchBar: UISearchBar) -> Bool {
    view.removeGestureRecognizer(tapGestureRecognizer!)
    return true
}

ユーザーが self.view に触れたとき:

func handleTap(recognizer: UITapGestureRecognizer) {
    sampleSearchBar.endEditing(true)
    sampleSearchBar.resignFirstResponder()
}
于 2016-06-01T06:17:22.620 に答える
-1

これは上記の回答に基づく私の解決策です...うまくいきました...

//Create tap gesture for menu transparent view
UITapGestureRecognizer *rightTableTransparentViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(rightTableTransparentViewTapMethod:)];
[rightTableTransparentViewTap setCancelsTouchesInView:NO];
[_rightTableTransparentView addGestureRecognizer:rightTableTransparentViewTap];

- (void)rightTableTransparentViewTapMethod:(UITapGestureRecognizer *)recognizer {
    //Write your code here
}
于 2018-04-12T06:31:26.723 に答える