UIImageView의 UIGestureRecognizer


179

나는이 UIImageView회전 등의 크기를 조정하고 내가 할 수 할을,

UIGestureRecognizer추가 할 수 있습니까 UIImageView?

UIImageView런타임에 생성되는 회전 및 핀치 인식기를 추가하고 싶습니다 .

이러한 인식기를 어떻게 추가합니까?

답변:


426

그 확인 userInteractionEnabled입니다 YESUIImageView. 그런 다음 제스처 인식기를 추가 할 수 있습니다.

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

5
아니요, 제스처 인식기를 추가하는 방법 만 보여줍니다. 제스처 핸들러에서 실제 확대 / 축소를 수행해야합니다. 줌 / 회전 방법에 대한 샘플 앱 Touches_GestureRecognizers 를 참조하십시오 .

77
+1은 내 제스처가 작동하지 않는 이유를 알아 내기 위해 여기에 앉아있었습니다. "UIImageView에서 userInteractionEnabled가 YES인지 확인하십시오." 감사!
Critter

1
이를 통해 인식기 세트의 한계를 전체 뷰로 설정하는 것보다 작업이 쉬워졌습니다. 감사!
Josh Kovach

6
imageView.userInteractionEnabled = 예; 이것이 열쇠입니다! 감사합니다.
HamasN

3
userInteractionEnabled여전히 목표 - C / 스위프트 엑스 코드 8 YES / true로 설정해야합니다
리앤

76

예, UIGestureRecognizer를 UIImageView에 추가 할 수 있습니다. 다른 답변에서 언급했듯이 userInteractionEnabled속성을 로 설정하여 이미지보기에서 사용자 상호 작용을 활성화하는 것이 중요 합니다 YES. UIImageView는 사용자 상호 작용 속성이 YES기본적으로 설정된 UIView에서 상속 되지만 UIImageView의 사용자 상호 작용 속성은 NO기본적으로 설정되어 있습니다.

로부터 의 UIImageView 워드 프로세서 :

새 이미지보기 개체는 기본적으로 사용자 이벤트를 무시하도록 구성되어 있습니다. UIImageView의 사용자 정의 서브 클래스에서 이벤트를 처리하려면 오브젝트를 초기화 한 후 userInteractionEnabled 특성 값을 YES로 명시 적으로 변경해야합니다.

어쨌든, 대부분의 대답. , a 및 a UIImageView로 a 를 만드는 방법의 예는 다음과 같습니다 .UIPinchGestureRecognizerUIRotationGestureRecognizerUIPanGestureRecognizer

먼저 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>

실제 샘플 프로젝트에서 직접 코드를 사용하고 싶다면이 코드를 포함하여 만든 샘플 프로젝트를 여기에서 찾을 수 있습니다.


1
이것은 지금까지 stackoverflow.com에서 본 최고의 답변이며, 상세하고 잘 주석 처리되었으며 심지어 git에 대한 소스 코드를 포함합니다. 감사합니다
Alejandro Luengo

1
단계별로 명확하고 멋진 설명
Alvin

1
애플과 다른 사람들이 수십 년에 걸쳐 수십 개의 튜토리얼에서 한 번에 한두 페이지 씩 해 주셔서 감사합니다. iOS에는 가능한 많은 것들이 있어야한다고 생각하지만, 난독 화와 오해로 인해 우리에게 잃어 버렸습니다.
잭 모리스

좋은 답변, 최고의 답변입니다. 양해 해 주셔서 감사합니다.
Jorg B Jorge

13

스위프트 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

스위프트 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)
    }
}

1
나는 여기에 대한 블로그를 썼습니다 : codebeaulieu.com/3/UIGestureRecognier-programatically
Dan Beaulieu

6

방금 단일보기로 3 개의 제스처를 추가하여 swift4 로이 작업을 수행했습니다.

  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

스위프트 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

탭 제스처 인식기를에서 이미지보기로 드래그 할 수도 있습니다 Storyboard. 그런 다음 ctrl + drag코드에 의해 조치를 작성 하십시오.


1

블록 애호가를 위해 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];
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.