【发布时间】:2014-03-20 19:39:35
【问题描述】:
我遇到了一个奇怪的错误(或者我真的很愚蠢......): 我想在 MKAnnotationView 中显示自定义标注。 我正在做的是添加一个自定义视图作为 MKAnnotationView 的子视图。 我在添加动画时遇到问题。
我有一个 MKMapView,我的视图控制器作为委托
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotationView
{
[self.calloutViewController setCalloutState:CalloutStateNormal
animated:YES
annotationView:annotationView
completion:NULL];
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)annotationView
{
[self.calloutViewController setCalloutState:CalloutStateHidden
animated:YES
annotationView:annotationView
completion:NULL];
}
self.calloutViewController 是一个自定义视图控制器,它创建一个气泡形状的视图(只是添加圆角和白色背景)。
- (void)setCalloutState:(CalloutState)calloutState
animated:(BOOL)animated
annotationView:(MKAnnotationView *)annotationView
completion:(void (^)(BOOL finished))completion
{
if (self.view.superview == annotationView || !annotationView) {
} else {
// [self.view.layer removeAllAnimations];
[self.view removeFromSuperview];
self.view.transform = CGAffineTransformIdentity;
self.view.bounds = CGRectMake(0, 0, normalViewWidth, normalViewHeight);
self.view.transform = CGAffineTransformMakeScale(0, 0);
self.view.center = CGPointMake(annotationView.bounds.size.width / 2, 0);
[annotationView addSubview:self.view];
}
void (^animationBlock)(void) = ^{
self.view.transform = CGAffineTransformIdentity;
switch (calloutState) {
case CalloutStateHidden:
self.view.bounds = CGRectMake(0, 0, normalViewWidth, normalViewHeight);
self.view.transform = CGAffineTransformMakeScale(0, 0);
break;
case CalloutStateNormal:
self.view.bounds = CGRectMake(0, 0, normalViewWidth, normalViewHeight);
break;
case CalloutStateExpanded:
self.view.bounds = CGRectMake(0, 0, expandedViewWidth, expandedViewHeight);
break;
default:
break;
}
self.view.center = CGPointMake(annotationView.bounds.size.width / 2, 0);
[self.view layoutIfNeeded];
};
if (animated) {
// TODO: figure out why the first animateWithDuration is needed in this nested thing
[UIView animateWithDuration:0
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:NULL
completion:^(BOOL finished) {
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:animationBlock
completion:^(BOOL finished) {
if (finished) {
self.calloutState = calloutState;
// TODO: figure out how to end UIView animation instantly so we don't need the second condition at the if
// having a concurrency problem here
if (calloutState == CalloutStateHidden && self.view.superview == annotationView) {
[self.view removeFromSuperview];
}
self.editingEnabled = calloutState == CalloutStateExpanded;
}
if (completion) {
completion(finished);
}
}];
}];
// ---------------------------------------------------------------------------------
} else {
animationBlock();
self.calloutState = calloutState;
if (calloutState == CalloutStateHidden) {
[self.view removeFromSuperview];
}
self.editingEnabled = calloutState == CalloutStateExpanded;
if (completion) {
completion(YES);
}
}
}
问题是: - 如果我在地图上选择一个图钉 (MKAnnotationView),它会正确显示我创建的标注气泡。 - 之后,我点击了一个不同的图钉(而气泡仍然显示在最后一个图钉中)。 - 然后使用选项 1) 标注气泡只是从一个引脚跳到另一个引脚,而不会为其缩放设置动画。 - 使用选项 2) 它可以正常工作。
我想了解为什么选项 1) 不起作用。 我不认为它应该有任何区别,因为当我点击第二个图钉时没有动画发生。
提前致谢。
编辑: 为简化起见,我创建了一个项目,其中包含重现我的问题所需的最少代码量:
@interface TestViewController () <MKMapViewDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (strong, nonatomic) UIView *customCallout;
@end
@implementation TestViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.customCallout = [[UIView alloc] initWithFrame:CGRectMake(-50, -50, 100, 50)];
self.customCallout.backgroundColor = [UIColor colorWithWhite:1 alpha:0.7];
self.mapView.delegate = self;
CustomAnnotation *annoation1 = [CustomAnnotation new];
annoation1.coordinate = CLLocationCoordinate2DMake(40, -100);
[self.mapView addAnnotation:annoation1];
CustomAnnotation *annoation2 = [CustomAnnotation new];
annoation2.coordinate = CLLocationCoordinate2DMake(40, -90);
[self.mapView addAnnotation:annoation2];
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
[self.customCallout removeFromSuperview];
self.customCallout.transform = CGAffineTransformMakeScale(0, 0);
[view addSubview:self.customCallout];
// [UIView animateWithDuration:0
// delay:0
// options:UIViewAnimationOptionBeginFromCurrentState
// animations:NULL
// completion:^(BOOL finished) {
[UIView animateWithDuration:1
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
self.customCallout.transform = CGAffineTransformIdentity;
}
completion:NULL];
// }];
}
@end
就像以前一样,第一次点击一个注释时,它可以正常工作,但是当您点击第二个注释时,动画不会发生。如果您取消注释注释的代码,它可以正常工作。
【问题讨论】:
标签: ios iphone objective-c animation uiview