it-swarm.com.ru

UIGestureRecognizer на UIImageView

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

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

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

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

171
jarryd

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

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

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

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

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

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

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

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

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

@interface MyClass : MySuperClass <UIGestureRecognizerDelegate>

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

73
Mick MacCallum

Решение Swift 2.0

Вы создаете распознавание жестов касанием, пинчем или проведением пальцем в той же усадьбе. Ниже я проведу вас через 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)
    }
}
11
Dan Beaulieu

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")
}
10
ayalcinkaya

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

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

3
mourodrigo

Я только что сделал это с 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
Leang Socheat

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

2
goggelj

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