Как добавить событие касания к 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
. После этого вы можете добавить его в представление.
Таким образом вы будете использовать композицию вместо подклассификации (которая была запросом).