40

UIView がタッチダウンされ、UIView がタップされていることを検出する方法を決定するという問題に悩まされています。タッチダウンすると、UIView の背景色が変わります。触れたときに、UIView に特定のタスクを実行させたいと思います。どうすればこの問題を解決できるか知りたいです。

-(void)viewDidLoad
{        
    UITapGestureRecognizer *dismissGestureRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDismissDoubleTap:)];
    dismissGestureRecognition.numberOfTapsRequired = 1;
    [sectionDismissDoubleView addGestureRecognizer:dismissGestureRecognition];

    UITapGestureRecognizer *dismissGestureDownRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissGestureDownRecognition:)];
    dismissGestureRecognition.numberOfTouchesRequired = 1;
    [sectionDismissDoubleView addGestureRecognizer:dismissGestureDownRecognition];
}

- (void)handleDismissDoubleTap:(UIGestureRecognizer*)tap {
    SettingsDismissDoubleViewController *settingsDouble = [[SettingsDismissDoubleViewController alloc] initWithNibName:@"SettingsDismissDoubleViewController" bundle:nil];
    [self.navigationController pushViewController:settingsDouble animated:YES];
}

- (void)dismissGestureDownRecognition:(UIGestureRecognizer*)tap {
    NSLog(@"Down");
}
4

5 に答える 5

61

ここに画像の説明を入力

このメソッドは、何もサブクラス化する必要はありません。UILongPressGestureRecognizerビューに a を追加し、minimumPressDurationをゼロに設定するだけです。次に、ジェスチャ イベントが呼び出されたときの状態をチェックして、タッチ イベントが開始または終了しているかどうかを確認します。

上記のサンプル画像のプロジェクト コード全体を次に示します。

import UIKit
class ViewController: UIViewController {
    @IBOutlet weak var myView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
        let tap = UILongPressGestureRecognizer(target: self, action: #selector(tapHandler))
        tap.minimumPressDuration = 0
        myView.addGestureRecognizer(tap)
    }

    @objc func tapHandler(gesture: UITapGestureRecognizer) {
        
        // there are seven possible events which must be handled

        if gesture.state == .began {
            myView.backgroundColor = UIColor.darkGray
            return
        }

        if gesture.state == .changed {
            print("very likely, just that the finger wiggled around while the user was holding down the button. generally, just ignore this")
            return
        }

        if gesture.state == .possible || gesture.state == .recognized {
            print("in almost all cases, simply ignore these two, unless you are creating very unusual custom subclasses")
            return
        }

        // the three remaining states are
        // .cancelled, .failed, and .ended
        // in all three cases, must return to the normal button look:
        myView.backgroundColor = UIColor.lightGray
    }
}

アイデアに対するこの回答に感謝します。

于 2016-07-01T10:45:12.183 に答える
45

Gesture Recognizer は、おそらく必要以上のものです。-touchesBegan:withEvent:おそらく、との組み合わせを使用したいだけでしょう-touchesEnded:withEvent:

これには欠陥がありますが、何をしたいのかというアイデアが得られるはずです。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.touchDown = YES;
    self.backgroundColor = [UIColor redColor];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Triggered when touch is released
    if (self.isTouchDown) {
        self.backgroundColor = [UIColor whiteColor];
        self.touchDown = NO;
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Triggered if touch leaves view
    if (self.isTouchDown) {
        self.backgroundColor = [UIColor whiteColor];
        self.touchDown = NO;
    }
}

このコードは、作成したカスタム サブクラスにUIView入れる必要があります。次に、代わりにこのカスタム ビュー タイプを使用するUIViewと、タッチ処理が得られます。

于 2013-10-26T22:10:00.350 に答える
6

すべての UIControl サブクラス (UIButton など) で、これを使用して特定の UIControlEvent のセットをサブスクライブできます。

addTarget:action:forControlEvents

UIControlEventTouchDown の適切なセレクターと UIControlEventTouchUpInside イベントの別のターゲット/セレクターを使用してターゲットを追加する必要があります。

UIControl リファレンス

于 2013-10-26T21:30:09.987 に答える
4

ホリーの答えのおかげで、私はButtonView便利なクラスを構築しました。

編集:この回答が示すように、UILongPressGestureRecognizer反応が非常に速いため、クラスを更新しました。

使用法:

let btn = ButtonView()
btn.onNormal = { btn.backgroundColor = .clearColor() }
btn.onPressed = { btn.backgroundColor = .blueColor() }
btn.onReleased = yourAction // Function to be called

クラス:

/** View that can be pressed like a button */

import UIKit

class ButtonView : UIView {

    /* Called when the view goes to normal state (set desired appearance) */
    var onNormal = {}
    /* Called when the view goes to pressed state (set desired appearance) */
    var onPressed = {}
    /* Called when the view is released (perform desired action) */
    var onReleased = {}

    override init(frame: CGRect)
    {
        super.init(frame: frame)

        let recognizer = UILongPressGestureRecognizer(target: self, action: Selector("touched:"))
        recognizer.delegate = self
        recognizer.minimumPressDuration = 0.0
        addGestureRecognizer(recognizer)
        userInteractionEnabled = true

        onNormal()
    }

    func touched(sender: UILongPressGestureRecognizer)
    {
        if sender.state == .Began {
            onPressed(self)
        } else if sender.state == .Ended {
            onNormal(self)
            onReleased()
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
于 2016-03-10T12:55:38.970 に答える
1

まず、あなたのセレクターによって、閉じるhandleDismissDoubleTap:ダブルタップを探していると思います。これを達成するには、次のことを行う必要があります。dismissGestureRecognition.numberOfTapsRequired = 2;

第 2 に、タッチ ダウンが長時間のタップ (または「タップ アンド ホールド」) のようなジェスチャーを意味する場合は、 のUILongPressGestureRecognizer代わりに を使用する必要がありUITapGestureRecognizerます。

于 2013-10-26T20:44:19.820 に答える