У меня есть экземпляр MKMapView
и хотел бы использовать пользовательские значки аннотации вместо стандартных значков контакта, предоставленных MKPinAnnotationView. Так, я имею, устанавливают подкласс MKAnnotationView по имени CustomMapAnnotation, и является переопределяющим -(void)drawRect:
потянуть CGImage. Это работает.
Проблема прибывает, когда я пытаюсь копировать .animatesDrop
функциональность предоставляется MKPinAnnotationView; я хотел бы в свои значки казаться постепенно, отброшенным сверху и в слева направо порядке, когда аннотации добавляются к MKMapView
экземпляр.
Вот - (пустой) drawRect: для CustomMapAnnotation, который работает, когда Вы просто тянете UIImage (который является тем, что 2-я строка делает):
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
[((Incident *)self.annotation).smallIcon drawInRect:rect];
if (newAnnotation) {
[self animateDrop];
newAnnotation = NO;
}
}
Проблема прибывает, когда Вы добавляете animateDrop
метод:
-(void)animateDrop {
CGContextRef myContext = UIGraphicsGetCurrentContext();
CGPoint finalPos = self.center;
CGPoint startPos = CGPointMake(self.center.x, self.center.y-480.0);
self.layer.position = startPos;
CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:@"position"];
theAnimation.fromValue=[NSValue valueWithCGPoint:startPos];
theAnimation.toValue=[NSValue valueWithCGPoint:finalPos];
theAnimation.removedOnCompletion = NO;
theAnimation.fillMode = kCAFillModeForwards;
theAnimation.delegate = self;
theAnimation.beginTime = 5.0 * (self.center.x/320.0);
theAnimation.duration = 1.0;
[self.layer addAnimation:theAnimation forKey:@""];
}
Это просто не работает, и могло быть много причин почему. Я не войду во всех них теперь. Главное, которое я желаю знать, состоит в том, если подход является звуковым вообще, или если я должен попробовать что-то совершенно различное.
Я попробовал также к пакету все это в транзакцию анимации так, чтобы beginTime параметр мог бы на самом деле работать; это, казалось, не сделало что-либо вообще. Я не знаю, является ли это вызвано тем, что я упускаю некоторую ключевую суть или является ли это, потому что MapKit повреждает мои анимации так или иначе.
// Does nothing
[CATransaction begin];
[map addAnnotations:list];
[CATransaction commit];
Если у кого-либо есть опыт с анимированным MKMapAnnotations как это, я любил бы некоторые подсказки, иначе если бы можно дать совет CAAnimation относительно подхода, это было бы большим также.
Сначала необходимо заставить контроллер просмотра реализовать MKMapViewDelegate, если он еще этого не сделал.
Затем, реализуйте этот метод:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
MKAnnotationView *aV;
for (aV in views) {
CGRect endFrame = aV.frame;
aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y - 230.0, aV.frame.size.width, aV.frame.size.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.45];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[aV setFrame:endFrame];
[UIView commitAnimations];
}
}
Добавьте свои аннотации в MapView, и когда они будут добавлены, этот метод делегирования будет вызываться и будет анимировать контакты сверху вниз по мере их добавления.
Значения для синхронизации и позиционирования могут быть немного изменены, но я настроил его так, чтобы он выглядел лучше/ближе к традиционному падению (насколько я тестировал). Надеюсь, это поможет!
В качестве альтернативы, если вы создаете подкласс MKAnnotationView, вы можете использовать didMoveToSuperview
для запуска анимации. Ниже приведено падение, которое заканчивается легким эффектом «сплющивания»
#define kDropCompressAmount 0.1
@implementation MyAnnotationViewSubclass
...
- (void)didMoveToSuperview {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
animation.duration = 0.4;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, -400, 0)];
animation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"transform"];
animation2.duration = 0.10;
animation2.beginTime = animation.duration;
animation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
animation2.toValue = [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(0, self.layer.frame.size.height*kDropCompressAmount, 0), 1.0, 1.0-kDropCompressAmount, 1.0)];
animation2.fillMode = kCAFillModeForwards;
CABasicAnimation *animation3 = [CABasicAnimation animationWithKeyPath:@"transform"];
animation3.duration = 0.15;
animation3.beginTime = animation.duration+animation2.duration;
animation3.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
animation3.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
animation3.fillMode = kCAFillModeForwards;
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = [NSArray arrayWithObjects:animation, animation2, animation3, nil];
group.duration = animation.duration+animation2.duration+animation3.duration;
group.fillMode = kCAFillModeForwards;
[self.layer addAnimation:group forKey:nil];
}