2013-11-02 72 views
4

我正在嘗試做一個圈圈蒙版圖像視圖,動畫蒙版,並使用不同的解決方案。下面的例子是做這個工作,但我有兩個問題:圓圈蒙面視圖動畫速度太快,無法點擊

1)爲什麼我不能使圖像可點擊?添加例如。 UITapGestureRecognizer不起作用。我的猜測是,遮罩可防止觸控操作傳播到視圖層次結構中的較低級別。

2)動畫的面具運行速度非常快,並使用UIView塊動畫

我怎樣才能解決這些我無法調整時間

- (void) addCircle { 
    // this is the encapsulating view 
    // 
    base = [[UIView alloc] init]; 
    // 
    // this is the button background 
    // 
    base_bgr = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"c1_bgr.png"]]; 
    base_bgr.center = CGPointMake(60, 140); 
    [base addSubview:base_bgr]; 
    // 
    // icon image 
    // 
    base_icon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"c1_ico.png"]]; 
    base_icon.center = CGPointMake(186*0.3/2, 182*0.3/2); 
    base_icon.transform = CGAffineTransformMakeScale(0.3, 0.3); 
    [base addSubview:base_icon]; 
    // 
    // the drawn circle mask layer 
    // 
    circleLayer = [CAShapeLayer layer]; 
    // Give the layer the same bounds as your image view 
    [circleLayer setBounds:CGRectMake(0.0f, 0.0f, [base_icon frame].size.width, 
             [base_icon frame].size.height)]; 
    // Position the circle 
    [circleLayer setPosition:CGPointMake(186*0.3/2-7, 182*0.3/2-10)]; 
    // Create a circle path. 
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect: 
          CGRectMake(0.0f, 0.0f, 70.0f, 70.0f)]; 
    // Set the path on the layer 
    [circleLayer setPath:[path CGPath]]; 

    [[base layer] setMask:circleLayer]; 

    [self.view addSubview:base]; 
    base.center = CGPointMake(100, 100); 
    base.userInteractionEnabled = YES; 
    base_bgr.userInteractionEnabled = YES; 
    base_icon.userInteractionEnabled = YES; 

    // 
    // NOT working: UITapGestureRecognizer 
    // 
    UITapGestureRecognizer *tapgesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapit:)]; 
    [base_icon addGestureRecognizer:tapgesture]; 

    // 
    // BAD but WORKS :) properly positioned UIButton over the masked image 
    // 
    base_btn = [UIButton buttonWithType:UIButtonTypeCustom]; 
    base_btn.frame = CGRectMake(base.frame.origin.x, base.frame.origin.y, base_icon.frame.size.width, base_icon.frame.size.height); 
    [base_btn addTarget:self action:@selector(tapit:) forControlEvents:UIControlEventTouchUpInside]; 
    [self.view addSubview:base_btn]; 
} 

這是tap處理程序,這裏是蒙版動畫。無論我嘗試持續多少次,它的動畫速度都很快 - 大約爲0.25秒,我無法調整它。因爲它沒有一個框架發起

- (void) tapit:(id) sender { 
    //... 
     [UIView animateWithDuration:1.0 
           delay:0.0 
          options:UIViewAnimationOptionCurveEaseOut 
         animations:^ { 
          [circleLayer setTransform:CATransform3DMakeScale(10.0, 10.0, 1.0)]; 
         } 
         completion:^(BOOL finished) { 
          // it is not necessary if I manage to make the icon image tappable 
          base_btn.frame = [base convertRect:base_icon.frame toView:self.view]; 
         }]; 
    }  
} 
+0

如果Base沒有觸及,tapit會在第一時間被調用嗎? – Unheilig

回答

1

1)觸摸沒有從base向下傳播,所以它的框架將是CGRectZero。視圖不會獲得超出界限的觸摸事件。只需在base上設置一個有效的框架,其中包含整個點擊目標。

2)setTransform:在一個圖層上調用一個使用Core Animation的默認持續時間爲0.25的隱式動畫(你猜對了:))。最好的解決方案是使用CABasicAnimation而不是基於UIView的動畫。事情是這樣的:

CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 
scaleAnimation.toValue = @(10.0f); 
scaleAnimation.duration = 2; 
[circleLayer addAnimation:scaleAnimation forKey:nil]; 

注:默認情況下,CABasicAnimation將自己從一個層時完全去除和層將彈回舊值。您可以通過例如將該動畫的removedOnCompletion屬性設置爲NO並稍後使用CALayerremoveAnimationForKey:方法(只需設置一個鍵而不是傳遞nil來添加動畫)來阻止它,但這取決於您想要完成的操作有了這個。

+1

經過測試和工作,thx!我關於保持CABasicAnimation最後階段的經驗是,我還必須包含fillMode = kCAFillModeForwards; – nzs