iOS 使用手勢UIGestureRecognizer對映像進行縮放、移動、旋轉等操作

來源:互聯網
上載者:User

UIGestureRecognizer 類

該類擁有一系列子類,每個子類都用於識別某類指定的手勢。它們是:

  • UITapGestureRecognizer – “輕擊”手勢。可以配置為“單擊”和“連擊”的識別。
  • UIPinchGestureRecognizer –“捏合”手勢。該手勢通常用於縮放視圖或改變可視組件的大小。
  • UIPanGestureRecognizer – “平移”手勢。識別拖拽或移動動作。
  • UISwipeGestureRecognizer – “輕掃”手勢。當使用者從螢幕上划過時識別為該手勢。可以指定該動作的方向(上、下、左、右)。
  • UIRotationGestureRecognizer – “轉動”手勢。使用者兩指在螢幕上做相對環形運動。
  • UILongPressGestureRecognizer – “長按”手勢。使用一指或多指觸控螢幕幕並保持一定時間。

這些手勢辨識器必需和視圖通過addGestureRecognizer:方法聯絡在一起。辨識器必需指定一個回應程式法以便發生指定手勢時進行調用。removeGestureRecognizer:方法可以將辨識器從視圖中移出,方法參數指定要移除的辨識器。

下面通過一個執行個體程式來分別介紹這些手勢,在一個視圖中增加一個UIImageView控制項,添加一個映像。對映像的操作都基於此視圖中進行。分別對這個映像使用這些手勢。

一、首先在一個視圖中添加一個imageview控制項,用以添加一個映像。

    self.productImageView.image = [UIImage imageNamed:@"iPhone.jpg"];

二、tap 手勢 (輕擊)

說明:在單擊中,實現的是視圖恢複,在雙擊中實現的是視圖放大/縮小一倍。

//輕點        // 單擊    UITapGestureRecognizer *SingleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(resetImage:)];    SingleTapGesture.numberOfTapsRequired = 1;//tap次數    [self.view addGestureRecognizer:SingleTapGesture];    // 雙擊    UITapGestureRecognizer *doubleTapGesture;    doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTapFrom)];    doubleTapGesture.numberOfTapsRequired = 2;     [self.view addGestureRecognizer:doubleTapGesture];    // 關鍵在這一行,如果雙擊確定偵測失敗才會觸發單擊    [SingleTapGesture requireGestureRecognizerToFail:doubleTapGesture];

回應程式法

//單擊恢複視圖- (void)resetImage:(UITapGestureRecognizer *)recognizer{    [UIView beginAnimations:nil context:nil];    [UIView setAnimationDuration:0.3];    // 恒等變換. beginAnimation 和 commitAnimation 間的操作為動畫過程    self.productImageView.transform = CGAffineTransformIdentity;    [self.productImageView setCenter:CGPointMake(self.view.frame.size.height/2, self.view.frame.size.width/2)];    [UIView commitAnimations];}//雙擊實現放大和縮小一倍- (void) handleDoubleTapFrom {    if (flag == YES) {        [UIView beginAnimations:nil context:nil];        [UIView setAnimationDuration:0.3];                [self.productImageView setFrame:CGRectMake(                                                   self.productImageView.frame.origin.x -self.productImageView.frame.size.width / 2,                                                   self.productImageView.frame.origin.y - self.productImageView.frame.size.height / 2,                                                   2 * self.productImageView.frame.size.width,                                                   2 * self.productImageView.frame.size.height)];        [UIView commitAnimations];        flag = NO;    }    else {        [UIView beginAnimations:nil context:nil];        [UIView setAnimationDuration:0.3];        [self.productImageView setFrame:CGRectMake(self.productImageView.frame.origin.x+self.productImageView.frame.size.width/4, self.productImageView.frame.origin.y + self.productImageView.frame.size.height/4, self.productImageView.frame.size.width/2, self.productImageView.frame.size.height/2)];        [UIView commitAnimations];        flag = YES;    }}

特別說明這個語句:

[SingleTapGesture requireGestureRecognizerToFail:doubleTapGesture];

有些手勢其實是互相關聯的,例如 Tap 與 LongPress、Swipe與 Pan,或是 Tap 一次與Tap 兩次。當一個 UIView 同時添加兩個相關聯的手勢時,到底我這一下手指頭按的要算是
Tap 還是 LongPress?如果照預設作法來看,只要先滿足條件的就會跳出並呼叫對應方法,舉例來說,如果同時註冊了 Pan 和 Swipe,只要手指頭一移動就會觸發 Pan 然後跳出,因而永遠都不會發生 Swipe;單點與雙點的情形也是一樣,永遠都只會觸發單點,不會有雙點。

那麼這個問題有解嗎?答案是肯定的,UIGestureRecognizer 有個方法叫做requireGestureRecognizerToFail,他可以指定某一個
recognizer,即便自己已經滿足條件了,也不會立刻觸發,會等到該指定的 recognizer 確定失敗之後才觸發。

二、pinch 手勢 (捏合縮放)

說明:在模擬器中 按住alt+滑鼠左鍵即可出現雙指觸控螢幕幕。

//捏合縮放    UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchView:)];    [self.view addGestureRecognizer:pinchGesture];  

回應程式法 (以下提供了兩種縮放回應程式法)

// 處理捏合縮放手勢- (void) pinchView:(UIPinchGestureRecognizer *)pinchGestureRecognizer{    UIView *view = self.productImageView;    if (pinchGestureRecognizer.state == UIGestureRecognizerStateBegan || pinchGestureRecognizer.state == UIGestureRecognizerStateChanged) {        view.transform = CGAffineTransformScale(view.transform, pinchGestureRecognizer.scale, pinchGestureRecognizer.scale);        pinchGestureRecognizer.scale = 1;    }}

- (void)scaleImage:(UIPinchGestureRecognizer *)recognizer {if([recognizer state] == UIGestureRecognizerStateEnded) {        // 如果Pinch 手勢結束,重設 previousScale 為 1.0self.previousScale = 1.0;return;}    CGFloat newScale = [recognizer scale]-self.previousScale +1.0;    CGAffineTransform currentTransformation = self.productImageView.transform;    // CGAffineTransformScale(currentTransformation, 1, 1) 變換保持原大小CGAffineTransform newTransform = CGAffineTransformScale(currentTransformation, newScale, newScale);    // perform the new transform    self.productImageView.transform = newTransform;    self.previousScale = [recognizer scale];}

三、pan 手勢 (平移)

 //平移    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panView:)];    [panGesture setMinimumNumberOfTouches:1];[panGesture setMaximumNumberOfTouches:1];    [self.view addGestureRecognizer:panGesture];

回應程式法

// 處理拖拉手勢- (void) panView:(UIPanGestureRecognizer *)panGestureRecognizer{    UIView *view = self.productImageView;    if (panGestureRecognizer.state == UIGestureRecognizerStateBegan || panGestureRecognizer.state == UIGestureRecognizerStateChanged) {               CGPoint translation = [panGestureRecognizer translationInView:view.superview];                [view setCenter:(CGPoint){view.center.x + translation.x, view.center.y + translation.y}];               [panGestureRecognizer setTranslation:CGPointZero inView:view.superview];    }}

四、rotate 手勢 (旋轉)

//旋轉    UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotateView:)];    [self.view addGestureRecognizer:rotationGesture];    

回應程式法

// 處理旋轉手勢- (void) rotateView:(UIRotationGestureRecognizer *)rotationGestureRecognizer{    UIView *view = self.productImageView;    if (rotationGestureRecognizer.state == UIGestureRecognizerStateBegan || rotationGestureRecognizer.state == UIGestureRecognizerStateChanged) {               view.transform = CGAffineTransformRotate(view.transform, rotationGestureRecognizer.rotation);                [rotationGestureRecognizer setRotation:0];    }}

最後還有一個要處理的就是模擬器的橫向擺放。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{    return ((interfaceOrientation == UIInterfaceOrientationLandscapeRight) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft));}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.