Odpowiedzi:
Sprawdź, czy userInteractionEnabled
jest YES
na UIImageView
. Następnie możesz dodać rozpoznawanie gestów.
imageView.userInteractionEnabled = YES;
UIPinchGestureRecognizer *pgr = [[UIPinchGestureRecognizer alloc]
initWithTarget:self action:@selector(handlePinch:)];
pgr.delegate = self;
[imageView addGestureRecognizer:pgr];
[pgr release];
:
:
- (void)handlePinch:(UIPinchGestureRecognizer *)pinchGestureRecognizer
{
//handle pinch...
}
userInteractionEnabled
nadal musi być ustawiony na TAK / prawda w Xcode 8 Objective-C / Swift
Tak, do UIImageView można dodać UIGestureRecognizer. Jak stwierdzono w drugiej odpowiedzi, bardzo ważne jest, aby pamiętać, aby umożliwić interakcję użytkownika w widoku obrazu poprzez ustawienie jego userInteractionEnabled
właściwości na YES
. UIImageView dziedziczy z UIView, którego właściwość interakcji użytkownika jest ustawiona YES
domyślnie, jednak właściwość interakcji użytkownika UIImageView jest ustawiona NO
domyślnie.
Nowe obiekty widoku obrazu są skonfigurowane tak, aby domyślnie ignorować zdarzenia użytkownika. Jeśli chcesz obsługiwać zdarzenia w niestandardowej podklasie UIImageView, musisz jawnie zmienić wartość właściwości userInteractionEnabled na YES po zainicjowaniu obiektu.
Tak czy inaczej, większość odpowiedzi. Oto przykład, jak utworzyć za UIImageView
pomocą a UIPinchGestureRecognizer
, a UIRotationGestureRecognizer
i a UIPanGestureRecognizer
.
Po pierwsze, viewDidLoad
lub inną wybraną metodą, utwórz widok obrazu, nadaj mu obraz, ramkę i włącz interakcję użytkownika. Następnie utwórz trzy gesty w następujący sposób. Pamiętaj, aby użyć ich właściwości delegowanej (najprawdopodobniej ustawionej na self). Będzie to konieczne, aby używać wielu gestów jednocześnie.
- (void)viewDidLoad
{
[super viewDidLoad];
// set up the image view
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImage"]];
[imageView setBounds:CGRectMake(0.0, 0.0, 120.0, 120.0)];
[imageView setCenter:self.view.center];
[imageView setUserInteractionEnabled:YES]; // <--- This is very important
// create and configure the pinch gesture
UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGestureDetected:)];
[pinchGestureRecognizer setDelegate:self];
[imageView addGestureRecognizer:pinchGestureRecognizer];
// create and configure the rotation gesture
UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGestureDetected:)];
[rotationGestureRecognizer setDelegate:self];
[imageView addGestureRecognizer:rotationGestureRecognizer];
// creat and configure the pan gesture
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureDetected:)];
[panGestureRecognizer setDelegate:self];
[imageView addGestureRecognizer:panGestureRecognizer];
[self.view addSubview:imageView]; // add the image view as a subview of the view controllers view
}
Oto trzy metody, które zostaną wywołane po wykryciu gestów w twoim widoku. Wewnątrz sprawdzimy aktualny stan gestu, a jeśli jest on w rozpoczęciu lub zmianie UIGestureRecognizerState
, odczytamy właściwość skali / obrotu / tłumaczenia gestu, zastosujemy te dane do transformacji afinicznej, zastosujemy transformację afiniczną do obrazu widok, a następnie zresetuj skalę / obrót / tłumaczenie gestów.
- (void)pinchGestureDetected:(UIPinchGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGFloat scale = [recognizer scale];
[recognizer.view setTransform:CGAffineTransformScale(recognizer.view.transform, scale, scale)];
[recognizer setScale:1.0];
}
}
- (void)rotationGestureDetected:(UIRotationGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGFloat rotation = [recognizer rotation];
[recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, rotation)];
[recognizer setRotation:0];
}
}
- (void)panGestureDetected:(UIPanGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGPoint translation = [recognizer translationInView:recognizer.view];
[recognizer.view setTransform:CGAffineTransformTranslate(recognizer.view.transform, translation.x, translation.y)];
[recognizer setTranslation:CGPointZero inView:recognizer.view];
}
}
Wreszcie, co bardzo ważne, musisz użyć metody UIGestureRecognizerDelegate , gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer
aby umożliwić jednoczesne działanie gestów. Jeśli te trzy gesty są jedynymi trzema gestami, którym przypisano tę klasę jako delegata, możesz po prostu powrócić, YES
jak pokazano poniżej. Jeśli jednak masz dodatkowe gesty, do których przypisano tę klasę jako ich delegata, może być konieczne dodanie logiki do tej metody, aby określić, który gest jest, przed umożliwieniem im wszystkim współpracy.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Nie zapomnij upewnić się, że twoja klasa jest zgodna z protokołem UIGestureRecognizerDelegate . Aby to zrobić, upewnij się, że interfejs wygląda mniej więcej tak:
@interface MyClass : MySuperClass <UIGestureRecognizerDelegate>
Jeśli wolisz sam bawić się kodem w działającym przykładowym projekcie, przykładowy projekt, który utworzyłem, zawierający ten kod, można znaleźć tutaj.
myImageView.isUserInteractionEnabled = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
tapGestureRecognizer.numberOfTapsRequired = 1
myImageView.addGestureRecognizer(tapGestureRecognizer)
a po stuknięciu:
@objc func imageTapped(_ sender: UITapGestureRecognizer) {
// do something when image tapped
print("image tapped")
}
W tej samej posiadłości tworzysz rozpoznawanie gestów dotykania, szczypania lub przeciągania. Poniżej przeprowadzę cię przez 4 kroki, aby uruchomić program rozpoznający.
4 kroki
1.) Dziedzicz UIGestureRecognizerDelegate
po dodaniu go do podpisu klasy.
class ViewController: UIViewController, UIGestureRecognizerDelegate {...}
2.) Kontroluj przeciąganie z obrazu do viewController, aby utworzyć IBOutlet:
@IBOutlet weak var tapView: UIImageView!
3.) W swoim viewDidLoad dodaj następujący kod:
// create an instance of UITapGestureRecognizer and tell it to run
// an action we'll call "handleTap:"
let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
// we use our delegate
tap.delegate = self
// allow for user interaction
tapView.userInteractionEnabled = true
// add tap as a gestureRecognizer to tapView
tapView.addGestureRecognizer(tap)
4.) Utwórz funkcję, która zostanie wywołana po stuknięciu rozpoznawania gestów. (Możesz wykluczyć, = nil
jeśli wybierzesz).
func handleTap(sender: UITapGestureRecognizer? = nil) {
// just creating an alert to prove our tap worked!
let tapAlert = UIAlertController(title: "hmmm...", message: "this actually worked?", preferredStyle: UIAlertControllerStyle.Alert)
tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
self.presentViewController(tapAlert, animated: true, completion: nil)
}
Twój końcowy kod powinien wyglądać mniej więcej tak:
class ViewController: UIViewController, UIGestureRecognizerDelegate {
@IBOutlet weak var tapView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
tap.delegate = self
tapView.userInteractionEnabled = true
tapView.addGestureRecognizer(tap)
}
func handleTap(sender: UITapGestureRecognizer? = nil) {
let tapAlert = UIAlertController(title: "hmmm...", message: "this actually worked?", preferredStyle: UIAlertControllerStyle.Alert)
tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
self.presentViewController(tapAlert, animated: true, completion: nil)
}
}
Właśnie to zrobiłem z swift4, dodając 3 gesty razem w jednym widoku
Oto mój przykładowy kod
class ViewController: UIViewController: UIGestureRecognizerDelegate{
//your image view that outlet from storyboard or xibs file.
@IBOutlet weak var imgView: UIImageView!
// declare gesture recognizer
var panRecognizer: UIPanGestureRecognizer?
var pinchRecognizer: UIPinchGestureRecognizer?
var rotateRecognizer: UIRotationGestureRecognizer?
override func viewDidLoad() {
super.viewDidLoad()
// Create gesture with target self(viewcontroller) and handler function.
self.panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.handlePan(recognizer:)))
self.pinchRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(self.handlePinch(recognizer:)))
self.rotateRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(self.handleRotate(recognizer:)))
//delegate gesture with UIGestureRecognizerDelegate
pinchRecognizer?.delegate = self
rotateRecognizer?.delegate = self
panRecognizer?.delegate = self
// than add gesture to imgView
self.imgView.addGestureRecognizer(panRecognizer!)
self.imgView.addGestureRecognizer(pinchRecognizer!)
self.imgView.addGestureRecognizer(rotateRecognizer!)
}
// handle UIPanGestureRecognizer
@objc func handlePan(recognizer: UIPanGestureRecognizer) {
let gview = recognizer.view
if recognizer.state == .began || recognizer.state == .changed {
let translation = recognizer.translation(in: gview?.superview)
gview?.center = CGPoint(x: (gview?.center.x)! + translation.x, y: (gview?.center.y)! + translation.y)
recognizer.setTranslation(CGPoint.zero, in: gview?.superview)
}
}
// handle UIPinchGestureRecognizer
@objc func handlePinch(recognizer: UIPinchGestureRecognizer) {
if recognizer.state == .began || recognizer.state == .changed {
recognizer.view?.transform = (recognizer.view?.transform.scaledBy(x: recognizer.scale, y: recognizer.scale))!
recognizer.scale = 1.0
}
}
// handle UIRotationGestureRecognizer
@objc func handleRotate(recognizer: UIRotationGestureRecognizer) {
if recognizer.state == .began || recognizer.state == .changed {
recognizer.view?.transform = (recognizer.view?.transform.rotated(by: recognizer.rotation))!
recognizer.rotation = 0.0
}
}
// mark sure you override this function to make gestures work together
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
Wszelkie pytania, po prostu wpisz komentarz. Dziękuję Ci
Przykład SWIFT 3
override func viewDidLoad() {
self.backgroundImageView.addGestureRecognizer(
UITapGestureRecognizer.init(target: self, action:#selector(didTapImageview(_:)))
)
self.backgroundImageView.isUserInteractionEnabled = true
}
func didTapImageview(_ sender: Any) {
// do something
}
W razie potrzeby nie można delegować narzędzia do rozpoznawania gestów ani innych implementacji.
Dla miłośnika bloków możesz użyć ALActionBlocks, aby dodać akcję gestów w bloku
__weak ALViewController *wSelf = self;
imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithBlock:^(UITapGestureRecognizer *weakGR) {
NSLog(@"pan %@", NSStringFromCGPoint([weakGR locationInView:wSelf.view]));
}];
[self.imageView addGestureRecognizer:gr];