gpt4 book ai didi

ios - 没有 UIViewAnimationOptionBeginFromCurrentState,UIView 动画无法工作

转载 作者:行者123 更新时间:2023-11-28 22:12:29 25 4
gpt4 key购买 nike

我遇到了一个奇怪的bug(或者我真的很笨……):我想在 MKAnnotationView 中显示自定义标注。我正在做的是添加一个自定义 View 作为 MKAnnotationView 的 subview 。我在添加动画时遇到问题。

我有一个 MKMapView,我的 View Controller 作为委托(delegate)

- (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 是一个自定义 View Controller ,它创建一个气泡形状的 View (只需添加圆角和白色背景)。

- (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);
}
}
}

问题是:- 如果我在 map 上选择一个图钉 (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

就像以前一样,第一次点击一个注释时,它工作正常,但是当你点击第二个注释时,动画不会发生。如果您取消注释注释代码,它工作正常。

最佳答案

UIViewAnimationOptionBeginFromCurrentState 从当前状态在屏幕上绘制开始动画,而不是从属性的当前值开始。因此,即使 View 的 transform 属性的值为 Scale(0, 0),它还没有将其绘制到屏幕上。额外的动画 block 有所不同的原因是,即使持续时间为 0,完成也不会立即执行,而是在下一次通过运行循环时执行,这为 View 提供了足够的时间来绘制自己。

如果删除 UIViewAnimationOptionBeginFromCurrentState 选项,动画将按预期工作:

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
[self.customCallout removeFromSuperview];
self.customCallout.transform = CGAffineTransformMakeScale(0, 0);
[view addSubview:self.customCallout];
[UIView animateWithDuration:1 animations:^{
self.customCallout.transform = CGAffineTransformIdentity;
}];
}

关于ios - 没有 UIViewAnimationOptionBeginFromCurrentState,UIView 动画无法工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22543431/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com