2014-03-27 40 views
0

我试图为注解视图的子视图的一些子视图设置动画。UIView块动画不从当前状态开始

所以,更清楚的是,灰色的针是我的注释视图,它有一个不可见的子视图,这个子视图包含这4个彩色圆视图。

annotation view 
| invisible view (called typeSelectionView) 
    | yellow view (called typeButton) 
    | blue view (called typeButton) 
    | green view (called typeButton) 
    | red view (called typeButton) 

enter image description here

首先圆圈是不可见的(变换尺度(0,0),并在灰色销的头部的中心),然后,当我选择灰度销,这些圆来从针头长出并移动到其原始位置(上图中的那个)。

当我取消选择该引脚时,会发生相反的动画。 当我在动画完成之前选择和取消选择(或相反)时,它会改变它的行进方式(如果它正在增长,它会缩小),在中间恢复动画。这就是为什么我需要UIViewAnimationOptionBeginFromCurrentState

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotationView 
{ 
    // in case the typeSelectionView was already being showed by another annotationView 
    if (self.typeSelectionView.superview != annotationView) { 
     [self.typeSelectionView removeFromSuperview]; 
     [self.typeSelectionView showTypeButtons:NO animated:NO completion:NULL]; 
    } 

    [annotationView addSubview:self.typeSelectionView]; 
    [self.typeSelectionView showTypeButtons:YES animated:YES completion:NULL]; 
} 

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)annotationView 
{ 
    if (self.typeSelectionView.superview) { 
     [self.typeSelectionView showTypeButtons:NO 
             animated:YES 
            completion:^(BOOL finished) { 
             if (finished) { 
              [self.typeSelectionView removeFromSuperview]; 
             } 
            }]; 
    } 
} 

- (void)showTypeButtons:(BOOL)show animated:(BOOL)animated completion:(void (^)(BOOL))completion 
{ 
    void (^block)(void) = ^{ 
     for (int i = 0; i < self.typeButtons.count; i++) { 
      TypeButton *typeButton = self.typeButtons[i]; 

      if (show) { 
       typeButton.center = [self _typeButtonCenterForIndex:i numberOfButtons:self.typeButtons.count]; 
       typeButton.transform = CGAffineTransformIdentity; 
      } else { 
       typeButton.center = CGPointMake(viewWidth/2, viewheight + 5); // pin head center 
       typeButton.transform = CGAffineTransformMakeScale(0, 0); 
      } 
     } 
    }; 

    if (animated) { 
     [UIView animateWithDuration:0.5 
           delay:0 
          options:UIViewAnimationOptionBeginFromCurrentState 
         animations:block 
         completion:^(BOOL finished) { 
          if (completion) { 
           completion(finished); 
          } 
         }]; 
    } else { 
     block(); 

     if (completion) { 
      completion(YES); 
     } 
    } 
} 

到目前为止,没有问题,但是当一个灰色的引脚显示typeSelectionView(如上面的图片),然后我选择另一脚,是这样的部分:

if (self.typeSelectionView.superview != annotationView) { 
    [self.typeSelectionView removeFromSuperview]; 
    [self.typeSelectionView showTypeButtons:NO animated:NO completion:NULL]; 
} 

什么也没做。 4圈简单地从一个针跳到另一个没有任何动画。 我期望的是[self.typeSelectionView showTypeButtons:NO animated:NO completion:NULL];将这些按钮设置为“隐藏”(比例尺(0,0)并且居中在引脚的顶部)而没有任何动画(因为不可见视图不再有超视图了,所以他们甚至没有显示),然后当我将typeSelectionView添加到新的注释视图[annotationView addSubview:self.typeSelectionView];时,我使用[self.typeSelectionView showTypeButtons:YES animated:YES completion:NULL];再次将圆圈设置为原始位置。

顺便说一句,做[typeButton.layer removeAllAnimations]showTypeButtons:animated:completion:开头什么都不做。

我该如何解决这个问题?

在此先感谢。

编辑:(BONUS如果有人可以解释给我...帮助我解决这个问题)=)

假设圆圈上面显示类似的图片,那么这段代码:

NSLog(@"type selected"); 
[self.typeSelectionView showTypeButtons:NO 
           animated:YES 
          completion:^(BOOL finished) { 
           NSLog(@"finisheddddd: %d", finished); 
          }]; 

[self.typeSelectionView showTypeButtons:NO 
           animated:YES 
          completion:^(BOOL finished) { 
           NSLog(@"finished: %d", finished); 
          }]; 

产生以下输出:

type selected 
finished: 1 
finisheddddd: 1 

所以第二动画完成第一和两个动画与完成。 第二个动画(首先完成)在动画时间结束后立即结束。

O.o

+0

我得到了什么是你的动画,但无法理解你的问题.. –

+0

我的问题是,当圆圈显示在一个针的顶部,然后我点击另一个脚,圆瞬间从第一脚消失,出现在第二个引脚上,没有任何动画。 –

+0

我也很感激,如果你可以看看EDIT =) –

回答

-1

检查我编写但未经过测试的代码。请自己做个实验,让你的结果

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)annotationView 
{ 
if (self.typeSelectionView.superview) 
{ 
    [self.typeSelectionView showTypeButtons:NO 
            animated:YES 
           completion:^(BOOL finished) { 
            if (finished) { 
             [self.typeSelectionView removeFromSuperview]; 
            } 
           }]; 
} 
} 

- (void)showTypeButtons:(BOOL)show animated:(BOOL)animated completion:(void (^) (BOOL))completion 
{ 

[UIView animateWithDuration:(animated) ?0.5f : 0.0f 
         delay:(self.animationStarted)? 0.5 : 0.0 
        options:UIViewAnimationOptionBeginFromCurrentState 
       animations:^{ 
        self.animationStarted = YES; 
        [self setButtonVisible:show]; 
       } 
       completion:^(BOOL finished) { 
        self.animationStarted = NO; 
         if (completion) { 
          completion(finished); 
         } 
        }]; 
} 

-(void)setButtonVisible:(BOOL)visible 
{ 
[self.typeButtons enumerateObjectsUsingBlock:^(TypeButton typeButton, NSUInteger idx, BOOL *stop) { 
     if (visible) 
     { 
      typeButton.center = [self _typeButtonCenterForIndex:idx numberOfButtons:self.typeButtons.count]; 
      typeButton.transform = CGAffineTransformIdentity; 
     } 
     else 
     { 
      typeButton.center = CGPointMake(viewWidth/2, viewheight + 5); // pin head center 
      typeButton.transform = CGAffineTransformMakeScale(0, 0); 
     } 

}]; 
} 
+0

您是否更改过didDeselectAnnotationView方法中的任何内容? –

+0

我试过你的代码,并且当已经选择一个引脚并且我选择另一个引脚时,这些圆仍然在跳跃。另外,我注意到一些奇怪的延迟。感谢您试图帮助,虽然= /。 –

-1

原来,问题是,当我把我的typeButtons非动画,他们不会立即重绘,所以他们不改变自己目前的状态,所以会发生什么:

one mapView:didSelectAnnotationView: method call: 
- show the buttons animated 

***redraw cycle here*** 

another mapView:didSelectAnnotationView: method call: 
- hide the buttons non-animated 
(no redraw cycle here, so buttons are still showing) 
- show the buttons animated 

所以我想出了这个解决方案低劣:

- (void)showTypeButtons:(BOOL)show animated:(BOOL)animated completion:(void (^)(BOOL))completion 
{ 
    void (^block)(void) = ^{ 
     for (int i = 0; i < self.typeButtons.count; i++) { 
      TypeButton *typeButton = self.typeButtons[i]; 

      if (show) { 
       typeButton.center = [self _typeButtonCenterForIndex:i numberOfButtons:self.typeButtons.count]; 
       typeButton.transform = CGAffineTransformIdentity; 
      } else { 
       typeButton.center = CGPointMake(viewWidth/2, viewheight + 5); // pin head center 
       typeButton.transform = CGAffineTransformMakeScale(0, 0); 
      } 
     } 
    }; 

    if (animated) { 
     [UIView animateWithDuration:0.5 
           delay:0 
          options:self.typeButtonsChangedWithoutAnimation ? 0 : UIViewAnimationOptionBeginFromCurrentState 
         animations:block 
         completion:^(BOOL finished) { 
          if (completion) { 
           completion(finished); 
          } 
         }]; 
     self.typeButtonsChangedWithoutAnimation = NO; 
    } else { 
     self.typeButtonsChangedWithoutAnimation = YES; 

     block(); 

     if (completion) { 
      completion(YES); 
     } 
    } 
} 

没有UIViewAnimationOptionBeginFromCurrentState,动画从它的实际状态,而不是˚F开始从其绘制状态。

一个解决方案,我发现,但没有工作是:What is the most robust way to force a UIView to redraw? 即使没有工作,我不希望它要么...

顺便说一句,我不会接受这个答案,因为它很糟糕。 它实际上并没有解决我的问题,即改变当前状态,而不是通过它。 我只是发布它,以防有人看到并得到如何真正解决我的原始问题的想法。