UIGestureRecognizer на UIImageView - PullRequest
       6

UIGestureRecognizer на UIImageView

174 голосов
/ 11 октября 2010

У меня есть UIImageView, который я хочу иметь возможность изменять размеры и вращать и т. Д.

Можно ли добавить UIGestureRecognizer к UIImageView?

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

Как добавить эти распознаватели?

Ответы [ 8 ]

418 голосов
/ 11 октября 2010

Убедитесь, что userInteractionEnabled равно YES на UIImageView. Затем вы можете добавить распознаватель жестов.

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...
}
74 голосов
/ 04 сентября 2013

Да, UIGestureRecognizer может быть добавлен в UIImageView.Как указано в другом ответе, очень важно помнить, чтобы разрешить взаимодействие с пользователем в представлении изображения, установив его свойство userInteractionEnabled в YES.UIImageView наследует от UIView, чье свойство взаимодействия с пользователем установлено по умолчанию YES, однако свойство взаимодействия с пользователем UIImageView установлено по умолчанию NO.

Из документов UIImageView:

Новые объекты просмотра изображений по умолчанию настроены на игнорирование пользовательских событий.Если вы хотите обрабатывать события в пользовательском подклассе UIImageView, вы должны явно изменить значение свойства userInteractionEnabled на YES после инициализации объекта.

В любом случае, в основном ответе.Вот пример того, как создать UIImageView с UIPinchGestureRecognizer, UIRotationGestureRecognizer и UIPanGestureRecognizer.

Сначала, в viewDidLoad или другим способом по вашему выбору, создайтепросмотрите изображение, дайте ему изображение, рамку и включите его взаимодействие с пользователем.Затем создайте три жеста следующим образом.Обязательно используйте их свойство делегата (скорее всего, для него установлено значение self).Для этого потребуется использовать несколько жестов одновременно.

- (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
}

Вот три метода, которые будут вызываться при обнаружении жестов на вашем виде.Внутри них мы проверим текущее состояние жеста, и если оно находится в начальном или измененном UIGestureRecognizerState, мы прочтем свойство масштаба / вращения / перевода жеста, применим эти данные к аффинному преобразованию, применим аффинное преобразованиек представлению изображения, а затем сбросьте масштаб жестов / вращение / перевод.

- (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];
    }
}

Наконец, что очень важно, вам нужно использовать UIGestureRecognizerDelegate метод gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer, чтобы жесты могли работать одновременно.Если эти три жеста являются единственными тремя жестами, которым этот класс назначен в качестве их делегата, то вы можете просто вернуть YES, как показано ниже.Однако, если у вас есть дополнительные жесты, которым этот класс назначен в качестве их делегата, вам может потребоваться добавить логику в этот метод, чтобы определить, какой это жест, прежде чем разрешить им всем работать вместе.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

Не делайтеНе забудьте убедиться, что ваш класс соответствует протоколу UIGestureRecognizerDelegate .Для этого убедитесь, что ваш интерфейс выглядит примерно так:

@interface MyClass : MySuperClass <UIGestureRecognizerDelegate>

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

12 голосов
/ 19 апреля 2015

Swift 4,2

myImageView.isUserInteractionEnabled = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
tapGestureRecognizer.numberOfTapsRequired = 1
myImageView.addGestureRecognizer(tapGestureRecognizer)

и при нажатии:

@objc func imageTapped(_ sender: UITapGestureRecognizer) {
   // do something when image tapped
   print("image tapped")
}
11 голосов
/ 08 июля 2015

Swift 2.0 Solution

В том же поместье вы создаете распознавание жестов касанием, сжиманием или проведением пальцем. Ниже я проведу вас через 4 шага, чтобы настроить и запустить ваш распознаватель.

4 шага

1.) Унаследуйте от UIGestureRecognizerDelegate, добавив его в подпись вашего класса.

class ViewController: UIViewController, UIGestureRecognizerDelegate {...}

2.) Управление перетаскиванием из вашего изображения в viewController для создания IBOutlet:

@IBOutlet weak var tapView: UIImageView!

3.) В ваш viewDidLoad добавьте следующий код:

// 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.) Создайте функцию, которая будет вызываться при нажатии на распознаватель жестов. (Вы можете исключить = nil, если хотите).

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)
}

Ваш окончательный код должен выглядеть примерно так:

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)
    }
}
3 голосов
/ 07 июля 2017

Я только что сделал это с swift4, добавив 3 жеста вместе в одном представлении

  1. UIPinchGestureRecognizer : увеличение и уменьшение масштаба.
  2. UIRotationGestureRecognizer : поворот представления.
  3. UIPanGestureRecognizer : перетаскивание вида.

Вот мой пример кода

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
     }

}

Любой вопрос, просто введите комментарий. спасибо

3 голосов
/ 22 декабря 2016

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
     }
}

Нет делегатов для распознавания жестов или других реализаций, где это необходимо.

2 голосов
/ 26 ноября 2015

Вы также можете перетащить распознаватель жестов касания к представлению изображения в раскадровке. Затем создайте действие, нажав Ctrl + Drag к коду ...

0 голосов
/ 27 декабря 2016

Для любителей блоков вы можете использовать ALActionBlocks , чтобы добавить действие жестов в блоке

__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];
...