Jak dodać zdarzenie touch do interfejsu UIView?
Jak dodać zdarzenie dotykowe do interfejsu UIView?
Staram się:
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:'
Nie chcę tworzyć podklasy i nadpisywać
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
15 answers
W systemie iOS 3.2 i nowszych można używać rozpoznawania gestów. Na przykład w ten sposób można obsłużyć Zdarzenie 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...
}
Istnieje również kilka wbudowanych gestów. Sprawdź dokumenty do obsługi zdarzeń iOS i UIGestureRecognizer
. Mam też kilka przykładowych kodów na github , które mogą pomóc.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-01 04:16:41
Rozpoznawanie Gestów
Istnieje wiele powszechnie używanych zdarzeń dotykowych (lub gestów), o których możesz być powiadamiany po dodaniu do widoku narzędzia rozpoznawania gestów . Domyślnie obsługiwane są następujące typy gestów:
-
UITapGestureRecognizer
dotknij (dotknij na krótko ekranu jeden lub więcej razy) -
UILongPressGestureRecognizer
długi dotyk (dotykanie ekranu przez długi czas) -
UIPanGestureRecognizer
Pan (poruszając palcem po screen) -
UISwipeGestureRecognizer
przesuń palcem (ruch palcem szybko) -
UIPinchGestureRecognizer
uszczypnij (przesuwając dwa palce razem lub osobno-zwykle w celu powiększenia) -
UIRotationGestureRecognizer
Obróć (poruszając dwoma palcami w kierunku kolistym)
Oprócz tych, można również zrobić własny rozpoznawania gestów niestandardowych.
Dodawanie gestu w Kreatorze interfejsów
Przeciągnij rozpoznawanie gestów z biblioteki obiektów na swój widok.
Sterowanie przeciąganiem z gestu w obrysie dokumentu do kodu kontrolera widoku, aby wykonać wyjście I Akcję.
Powinna być ustawiona domyślnie, ale także upewnij się, że User Action Enabled jest ustawiona na true dla Twojego widoku.
Dodawanie gestu programowo
Aby programowo dodać gest, należy (1) utworzyć rozpoznawanie gestów, (2) dodaj go do widoku i (3) Utwórz metodę, która zostanie wywołana, gdy gest zostanie rozpoznany.
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
@objc func handleTap(sender: UITapGestureRecognizer) {
print("tap")
}
}
Uwagi
- parametr
sender
jest opcjonalny. Jeśli nie potrzebujesz odniesienia do gestu, możesz go pominąć. Jeśli to zrobisz, Usuń(sender:)
po nazwie metody akcji.
Nazwa metody
handleTap
była Dowolna. Nazwij go jak chcesz używając action: #selector(someMethodName(sender:))
.
Więcej Przykładów
Możesz studiować rozpoznawanie gestów że dodałem do tych poglądów, aby zobaczyć, jak działają.
Oto kod do tego projektu:
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
@objc 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
@objc 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
@objc 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
@objc 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
@objc 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
@objc 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
@objc func handleRotate(gesture: UIRotationGestureRecognizer) {
label.text = "Rotate recognized"
if gesture.state == UIGestureRecognizerState.changed {
let transform = CGAffineTransform(rotationAngle: gesture.rotation)
rotateView.transform = transform
}
}
}
Uwagi
- do jednego widoku można dodać wiele funkcji rozpoznawania gestów. Ze względu na prostotę, nie zrobiłem tego(z wyjątkiem gestu machnięcia). Jeśli potrzebujesz do swojego projektu, powinieneś przeczytać dokumentacja rozpoznawania gestów . Jest to dość zrozumiałe i pomocne.
- Znane problemy z moje przykłady powyżej: (1) widok panoramiczny resetuje swoją klatkę przy następnym zdarzeniu gest. (2) widok Przesuń pochodzi z niewłaściwym kierunku przy pierwszym przesunięciu. (Te błędy w moich przykładach nie powinny mieć wpływu na zrozumienie, jak działają Rozpoznawacze gestów.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Myślę, że możesz po prostu użyć
UIControl *headerView = ...
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];
Chodzi mi o to, że headerView rozszerza się z UIControl.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 01:37:53
Swift 3 & Swift 4
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
}
}
Użyj
yourView.addTapGesture(tapNumber: 1, target: self, action: #selector(yourMethod))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-28 07:13:07
Na podstawie zaakceptowanej odpowiedzi można zdefiniować makro:
#define handle_tap(view, delegate, selector) do {\
view.userInteractionEnabled = YES;\
[view addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:delegate action:selector]];\
} while(0)
To makro używa ARC, więc nie ma release
wywołania.
Przykład użycia makra:
handle_tap(userpic, self, @selector(onTapUserpic:));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:07
W Swift 4.2 i Xcode 10
Użyj UITapGestureRecognizer aby dodać zdarzenie dotykowe
//Add tap gesture to your view
let tap = UITapGestureRecognizer(target: self, action: #selector(handleGesture))
yourView.addGestureRecognizer(tap)
// GestureRecognizer
@objc func handleGesture(gesture: UITapGestureRecognizer) -> Void {
//Write your code here
}
Jeśli chcesz użyć SharedClass
//This is my shared class
import UIKit
class SharedClass: NSObject {
static let sharedInstance = SharedClass()
//Tap gesture function
func addTapGesture(view: UIView, target: Any, action: Selector) {
let tap = UITapGestureRecognizer(target: target, action: action)
view.addGestureRecognizer(tap)
}
}
Mam 3 widoki w moim kontrolerze ViewController o nazwie view1, view2 i view3.
override func viewDidLoad() {
super.viewDidLoad()
//Add gestures to your views
SharedClass.sharedInstance.addTapGesture(view: view1, target: self, action: #selector(handleGesture))
SharedClass.sharedInstance.addTapGesture(view: view2, target: self, action: #selector(handleGesture))
SharedClass.sharedInstance.addTapGesture(view: view3, target: self, action: #selector(handleGesture2))
}
// GestureRecognizer
@objc func handleGesture(gesture: UITapGestureRecognizer) -> Void {
print("printed 1&2...")
}
// GestureRecognizer
@objc func handleGesture2(gesture: UITapGestureRecognizer) -> Void {
print("printed3...")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-12 08:50:34
Możesz to osiągnąć, dodając rozpoznawanie gestów w kodzie.
Krok 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];
Krok 2: ViewController.m:
// Declare the Gesture Recogniser handler method.
- (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer{
NSLog(@"Tapped");
}
Uwaga: tutaj twój widok w moim przypadku był @property (strong, nonatomic) IBOutlet UIView *localView;
EDIT: *localView jest białym polem W Main.storyboard from below
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-19 11:19:07
Heres a Swift version:
// 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
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-24 12:54:06
Swift 3:
let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGestureRecognizer(_:)))
view.addGestureRecognizer(tapGestureRecognizer)
func handleTapGestureRecognizer(_ gestureRecognizer: UITapGestureRecognizer) {
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-21 06:19:49
W dzisiejszych czasach wydaje się to dość proste. To jest wersja Swift.
let tap = UITapGestureRecognizer(target: self, action: #selector(viewTapped))
view.addGestureRecognizer(tap)
@objc func viewTapped(recognizer: UIGestureRecognizer)
{
//Do what you need to do!
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-16 06:38:56
Objective-C:
UIControl *headerView = [[UIControl alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, nextY)];
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];
Swift:
let headerView = UIControl(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: nextY))
headerView.addTarget(self, action: #selector(myEvent(_:)), for: .touchDown)
Pytanie zadaje:
Jak dodać zdarzenie touch do UIView?
To nie jest prośba o Zdarzenietap .
Konkretnie OP chce zaimplementować UIControlEventTouchDown
Zamiana UIView
na UIControl
jest tutaj właściwą odpowiedzią, ponieważ Gesture Recognisers
Nie wiem nic o .touchDown
, .touchUpInside
, .touchUpOutside
itd.
Dodatkowo, UIControl dziedziczy z UIView, więc nie tracisz żadnych funkcjonalność.
Jeśli chcesz tylko stuknąć, możesz użyć rozpoznawania gestów. Ale jeśli chcesz mieć lepszą kontrolę, o co prosi to pytanie, będziesz potrzebował UIControl.
Https://developer.apple.com/documentation/uikit/uicontrol?language=objc https://developer.apple.com/documentation/uikit/uigesturerecognizer?language=objc
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-14 14:05:10
Oto iOS tapgesture; Najpierw musisz utworzyć akcję dla GestureRecognizer po wpisaniu poniższego kodu pod akcją, jak pokazano poniżej
- (IBAction)tapgesture:(id)sender
{
[_password resignFirstResponder];
[_username resignFirstResponder];
NSLog(@" TapGestureRecognizer tapped");
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-31 05:48:58
Innym sposobem jest dodanie przezroczystego przycisku do widoku
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];
A następnie uchwyć kliknięcie:
- (void)buttonClicked:(id)sender
{}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-17 10:32:34
Utwórz podklasę rozpoznawania gestów, która zaimplementuje zdarzenia dotykowe, takie jak touchesBegan
. Możesz dodać go do widoku po tym.
W ten sposób użyjesz kompozycji zamiast podklasowania(co było żądaniem).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-13 17:11:13
Może spróbujecie SSEventListener ?
Nie musisz tworzyć żadnego rozpoznawania gestów i oddzielać logiki od innej metody. SSEventListener
obsługuje ustawianie bloków słuchacza w widoku, aby słuchać gestu pojedynczego dotknięcia, gestu podwójnego dotknięcia i gestu N-dotknięcia, jeśli chcesz, i długie naciśnięcie gestu. Ustawienie gestu pojedynczego dotknięcia odbywa się w ten sposób:
[view ss_addTapViewEventListener:^(UITapGestureRecognizer *recognizer) { ... } numberOfTapsRequired:1];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-15 06:53:55