UIGestureRecognizer в UIImageView

У меня есть UIImageView, который я хочу изменить и повернуть и т.д.

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

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

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

Ответ 1

Убедитесь, что 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...
}

Ответ 2

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

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

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

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

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

- (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, мы будем читать свойство шкалы шкалы/поворота/перевода, применим эти данные к аффинному преобразованию, применим аффинное преобразование к представлению изображения, а затем reset масштаб/поворот/перевод жестов.

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

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

Ответ 3

Решение Swift 2.0

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

4 шага

1.) Наследовать от UIGestureRecognizerDelegate, добавив его в подпись класса.

class ViewController: UIViewController, UIGestureRecognizerDelegate {...}

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

@IBOutlet weak var tapView: UIImageView!

3.) В вашем представленииDidLoad добавьте следующий код:

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

Ответ 4

Swift 4

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

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

func imageTapped(sender: UITapGestureRecognizer) {
   // do something when image tapped
   println("image tapped")
}

для любителей Swift:

    myImageView.userInteractionEnabled = true
    var tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "imageTapped:")
    tapGestureRecognizer.numberOfTapsRequired = 1
    myImageView.addGestureRecognizer(tapGestureRecognizer)

тогда при нажатии изображения:

func imageTapped(sender: UITapGestureRecognizer) {
   // do something when image tapped
   println("image tapped")
}

Ответ 5

Пример 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
     }
}

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

Ответ 6

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

  • UIPinchGestureRecognizer: просмотр и уменьшение масштаба.
  • UIRotationGestureRecognizer. Поверните представление.
  • 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
     }

}

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

Ответ 7

Вы также можете перетащить распознаватель жестов к изображению в Раскадке. Затем создайте действие ctrl + drag для кода...

Ответ 8

Для любовника Blocks вы можете использовать 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];