Как добавить событие касания к UIView?

Как добавить сенсорное событие в UIView?
Я пытаюсь:

UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, nextY)] autorelease];
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];
// ERROR MESSAGE: UIView may not respond to '-addTarget:action:forControlEvents:'

Я не хочу создавать подкласс и перезаписывать

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

Ответ 1

В iOS 3.2 и выше вы можете использовать распознаватели жестов. Например, так вы будете обрабатывать событие tap:

//The setup code (in viewDidLoad in your view controller)
UITapGestureRecognizer *singleFingerTap = 
  [[UITapGestureRecognizer alloc] initWithTarget:self 
                                          action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleFingerTap];

//The event handling method
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
  CGPoint location = [recognizer locationInView:[recognizer.view superview]];

  //Do stuff here...
}

Есть также куча встроенных жестов. Проверьте документы для обработки событий iOS и UIGestureRecognizer. У меня также есть куча примерного кода на github, который может помочь.

Ответ 2

Распознаватели жестов

Существует ряд часто используемых событий касания (или жестов), о которых вы можете получить уведомление о том, когда вы добавите Распознаватель жестов к вашему представлению. По умолчанию используются следующие типы жестов:

  • UITapGestureRecognizer Нажмите (кратковременно коснувшись экрана один раз)
  • UILongPressGestureRecognizer Длительное касание (долгое нажатие на экран)
  • UIPanGestureRecognizer Пан (перемещение пальца по экрану)
  • UISwipeGestureRecognizer Проведите по экрану (быстро перемещайте палец)
  • UIPinchGestureRecognizer Pinch (перемещение двух пальцев друг с другом - обычно для увеличения)
  • UIRotationGestureRecognizer Повернуть (перемещение двух пальцев в круговом направлении)

В дополнение к этому вы также можете создать свой собственный распознаватель жестов.

Добавление жестов в построитель интерфейсов

Перетащите распознаватель жестов из библиотеки объектов на ваш вид.

введите описание изображения здесь

Управляйте перетаскиванием с жестов в структуре документа на ваш код контроллера просмотра, чтобы сделать выход и действие.

введите описание изображения здесь

Добавление жеста программно

Чтобы добавить жест программно, вы (1) создаете распознаватель жестов, (2) добавляете его в представление и (3) создаете метод, который вызывается, когда распознается жест.

import UIKit
class ViewController: UIViewController {

    @IBOutlet weak var myView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // 1. create a gesture recognizer (tap gesture)
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))

        // 2. add the gesture recognizer to a view
        myView.addGestureRecognizer(tapGesture)
    }

    // 3. this method is called when a tap is recognized
    func handleTap(sender: UITapGestureRecognizer) {
        print("tap")
    }
}

Примечания

  • Параметр sender не является обязательным. Если вам не нужна ссылка на этот жест, вы можете оставить его. Если вы это сделаете, удалите (_:) после имени метода действия при создании жеста.
  • Именование метода handleTap было произвольным. Назовите его как хотите, используя action: #selector(someMethodName(sender:)).

Дополнительные примеры

Вы можете изучить распознаватели жестов, которые я добавил к этим представлениям, чтобы посмотреть, как они работают.

введите описание изображения здесь

Вот код для этого проекта:

import UIKit
class ViewController: UIViewController {

    @IBOutlet weak var tapView: UIView!
    @IBOutlet weak var doubleTapView: UIView!
    @IBOutlet weak var longPressView: UIView!
    @IBOutlet weak var panView: UIView!
    @IBOutlet weak var swipeView: UIView!
    @IBOutlet weak var pinchView: UIView!
    @IBOutlet weak var rotateView: UIView!
    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Tap
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        tapView.addGestureRecognizer(tapGesture)

        // Double Tap
        let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
        doubleTapGesture.numberOfTapsRequired = 2
        doubleTapView.addGestureRecognizer(doubleTapGesture)

        // Long Press
        let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(gesture:)))
        longPressView.addGestureRecognizer(longPressGesture)

        // Pan
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(gesture:)))
        panView.addGestureRecognizer(panGesture)

        // Swipe (right and left)
        let swipeRightGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(gesture:)))
        let swipeLeftGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(gesture:)))
        swipeRightGesture.direction = UISwipeGestureRecognizerDirection.right
        swipeLeftGesture.direction = UISwipeGestureRecognizerDirection.left
        swipeView.addGestureRecognizer(swipeRightGesture)
        swipeView.addGestureRecognizer(swipeLeftGesture)

        // Pinch
        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(gesture:)))
        pinchView.addGestureRecognizer(pinchGesture)

        // Rotate
        let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(handleRotate(gesture:)))
        rotateView.addGestureRecognizer(rotateGesture)

    }

    // Tap action
    func handleTap() {
        label.text = "Tap recognized"

        // example task: change background color
        if tapView.backgroundColor == UIColor.blue {
            tapView.backgroundColor = UIColor.red
        } else {
            tapView.backgroundColor = UIColor.blue
        }

    }

    // Double tap action
    func handleDoubleTap() {
        label.text = "Double tap recognized"

        // example task: change background color
        if doubleTapView.backgroundColor == UIColor.yellow {
            doubleTapView.backgroundColor = UIColor.green
        } else {
            doubleTapView.backgroundColor = UIColor.yellow
        }
    }

    // Long press action
    func handleLongPress(gesture: UILongPressGestureRecognizer) {
        label.text = "Long press recognized"

        // example task: show an alert
        if gesture.state == UIGestureRecognizerState.began {
            let alert = UIAlertController(title: "Long Press", message: "Can I help you?", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }

    // Pan action
    func handlePan(gesture: UIPanGestureRecognizer) {
        label.text = "Pan recognized"

        // example task: drag view
        let location = gesture.location(in: view) // root view
        panView.center = location
    }

    // Swipe action
    func handleSwipe(gesture: UISwipeGestureRecognizer) {
        label.text = "Swipe recognized"

        // example task: animate view off screen
        let originalLocation = swipeView.center
        if gesture.direction == UISwipeGestureRecognizerDirection.right {
            UIView.animate(withDuration: 0.5, animations: {
                self.swipeView.center.x += self.view.bounds.width
                }, completion: { (value: Bool) in
                    self.swipeView.center = originalLocation
            })
        } else if gesture.direction == UISwipeGestureRecognizerDirection.left {
            UIView.animate(withDuration: 0.5, animations: {
                self.swipeView.center.x -= self.view.bounds.width
                }, completion: { (value: Bool) in
                    self.swipeView.center = originalLocation
            })
        }
    }

    // Pinch action
    func handlePinch(gesture: UIPinchGestureRecognizer) {
        label.text = "Pinch recognized"

        if gesture.state == UIGestureRecognizerState.changed {
            let transform = CGAffineTransform(scaleX: gesture.scale, y: gesture.scale)
            pinchView.transform = transform
        }
    }

    // Rotate action
    func handleRotate(gesture: UIRotationGestureRecognizer) {
        label.text = "Rotate recognized"

        if gesture.state == UIGestureRecognizerState.changed {
            let transform = CGAffineTransform(rotationAngle: gesture.rotation)
            rotateView.transform = transform
        }
    }
}

Примечания

  • Вы можете добавить несколько распознавателей жестов в один вид. Однако для простоты я этого не делал (кроме жестов салфетки). Если вам нужно для вашего проекта, вы должны прочитать документацию распознавателя жестов. Это довольно понятно и полезно.
  • Известные проблемы с моими примерами выше: (1) Pan view сбрасывает свой фрейм в следующем событии жестов. (2) Вид прокрутки происходит из неправильного направления при первом прокрутке. (Эти ошибки в моих примерах не должны влиять на ваше понимание того, как работают распознаватели жестов).

Обновлен для Swift 3

Ответ 3

Я думаю, вы можете просто использовать

UIControl *headerView = ...
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];

i означает, что headerView продолжается от UIControl.

Ответ 4

В соответствии с принятым ответом вы можете определить макрос:

#define handle_tap(view, delegate, selector) do {\
    view.userInteractionEnabled = YES;\
    [view addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:delegate action:selector]];\
} while(0)

Этот макрос использует ARC, поэтому нет вызова release.

Пример использования макроса:

handle_tap(userpic, self, @selector(onTapUserpic:));

Ответ 5

Вы можете достичь этого, добавив в свой код распознаватель жестов.

Шаг 1: ViewController.m:

// Declare the Gesture.
UITapGestureRecognizer *gesRecognizer = [[UITapGestureRecognizer alloc] 
                                          initWithTarget:self 
                                          action:@selector(handleTap:)];
gesRecognizer.delegate = self;

// Add Gesture to your view.
[yourView addGestureRecognizer:gesRecognizer]; 

Шаг 2: ViewController.m:

// Declare the Gesture Recogniser handler method.
- (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer{
   NSLog(@"Tapped");
}

ПРИМЕЧАНИЕ: здесь myView в моем случае был @property (strong, nonatomic) IBOutlet UIView *localView;

EDIT: * localView - это белая рамка в Main.storyboard снизу

введите описание изображения здесь

введите описание изображения здесь

Ответ 6

Вот версия Swift:

// MARK: Gesture Extensions
extension UIView {

    func addTapGesture(#tapNumber: Int, target: AnyObject, action: Selector) {
        let tap = UITapGestureRecognizer (target: target, action: action)
        tap.numberOfTapsRequired = tapNumber
        addGestureRecognizer(tap)
        userInteractionEnabled = true
    }

    func addTapGesture(#tapNumber: Int, action: ((UITapGestureRecognizer)->())?) {
        let tap = BlockTap (tapCount: tapNumber, fingerCount: 1, action: action)
        addGestureRecognizer(tap)
        userInteractionEnabled = true
    }
}

Ответ 7

Обновление Swift 3

import UIKit

extension UIView {

func addTapGesture(tapNumber : Int, target: Any , action : Selector) {

    let tap = UITapGestureRecognizer(target: target, action: action)
    tap.numberOfTapsRequired = tapNumber
    addGestureRecognizer(tap)
    isUserInteractionEnabled = true

  }
}

Использовать

 yourView.addTapGesture(tapNumber: 1, target: self, action: #selector(yourMethod))

Ответ 8

Swift 3:

let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGestureRecognizer(_:)))
view.addGestureRecognizer(tapGestureRecognizer)

func handleTapGestureRecognizer(_ gestureRecognizer: UITapGestureRecognizer) {

}

Ответ 9

Здесь ios tapgesture; Сначала вам нужно создать действие для GestureRecognizer после написания ниже кода под действием, как показано ниже.

- (IBAction)tapgesture:(id)sender

{


[_password resignFirstResponder];


[_username resignFirstResponder];

NSLog(@" TapGestureRecognizer  tapped");

}

Ответ 10

Другим способом является добавление прозрачной кнопки в представление

UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
b.frame = CGRectMake(0, 0, headerView.width, headerView.height);
[headerView addSubview:b];
[b addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchDown];

И затем, дескриптор щелчка:

- (void)buttonClicked:(id)sender
{}

Ответ 11

Создайте распознаватель жестов (подкласс), который будет реализовывать события касания, например touchesBegan. После этого вы можете добавить его в представление.

Таким образом вы будете использовать композицию вместо подклассификации (которая была запросом).