Вращение отображаемого изображения MKAnnotationView
В настоящее время я вращаю свойство изображения MKAnnotationView, используя CGAffineTransformMakeRotation. Тем не менее, весь вид в этом случае поворачивается, а также пузырь выноски. Поэтому я следовал предложению в MKAnnotationView Only Rotate свойства Image, и теперь я создаю UIImageView и добавляю его как подпредставление в MKAnnotationView. Изображение отображается и вращается теперь без проблем. Однако теперь MKAnnotationView не реагирует на сенсорные события. Мне нужно, чтобы он вел себя так же, как и раньше - при прикосновении / прикосновении должно отображаться всплывающее окно. Есть идеи, что мне нужно сделать?
Первоначальный способ, которым я пытался (который вращает пузырь выноски):
MKAnnotationView *aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Pin"];
aView.image = [UIImage imageNamed:@"mapPin.png"];
float newRad = degreesToRadians(degreesToRotate);
[aView setTransform:CGAffineTransformRotate(CGAffineTransformIdentity, newRad)];
Использование UIImageView и добавление в качестве подпредставления:
MKAnnotationView *aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Pin"];
UIImageView *iv = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"mapPin.png"]];
iv.userInteractionEnabled = YES;
[aView addSubview:iv];
aView.canShowCallout = YES;
Обновление Я попытался добавить распознаватель жестов, хотя он не работает. Метод imageTapped не вызывается, когда я нажимаю на UIImageView в MKAnnotationView на карте. Это внутри метода: - (MKAnnotationView *)mapView:(MKMapView *)mView viewForAnnotation:(id) аннотация
MKAnnotationView *aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Pin"];
UIImageView *iv = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"mapPin.png"]];
iv.userInteractionEnabled = YES;
iv.exclusiveTouch = NO;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTapped:)];
[iv addGestureRecognizer:tapGesture];
[aView addSubview:iv];
5 ответов
Я понимаю, что это очень старый вопрос, но недавно я столкнулся с этой проблемой, и у нее было очень простое решение. Единственная причина, по которой вид аннотации становится неактивным при использовании вида изображения, заключается в том, что MKAnnotationView имеет размер (0,0), когда изображение не установлено. Представление изображения является видимым, потому что представление аннотации не ограничивает границы. Все, что мне нужно было сделать, это установить рамку в представлении аннотации, чтобы она снова стала кликабельной.
MKAnnotationView *aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Pin"];
UIImageView *iv = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"mapPin.png"]];
[aView addSubview:iv];
annotationView.frame = (CGRect) {
.origin = CGPointZero,
.size = iv.frame.size
};
aView.canShowCallout = YES;
Я попробовал все ответы здесь, и ни один из них не сработал полностью, но я нашел другое решение, которое сработало!
Я считаю, что самый простой способ сделать это повернуть UIImage
сам перед установкой image
собственность MKAnnotationView
, Если у вас есть сотни и сотни аннотаций, это может работать плохо, но если вам просто нужно повернуть пару вещей (как в моем случае), это работает просто отлично.
Я нашел вспомогательный класс для поворота UIImage, а затем просто использовал его для поворота UIImage перед установкой image
собственностью MKAnnotationView
,
Вспомогательный класс находится здесь: http://www.catamount.com/forums/viewtopic.php?f=21&t=967
Теперь, чтобы повернуть свойство UIImage MKAnnotationView на карте, не жертвуя выноской, сделайте следующее:
- (MKAnnotationView *)mapView:(MKMapView *)pMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MyAnnotationView *annotationView = [[MyAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"WayPoint"];
annotationView.image = [annotationView.image imageRotatedByDegrees:45.0];
annotationView.canShowCallout = YES;
return annotationView;
}
Попробуйте сделать что-то подобное в представлении изображения, чтобы посмотреть, сможете ли вы передать его сенсорное событие в аннотацию.
//Do this before you add the imageview as a subview
self.imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTapped:)];
[self.imageView addGestureRecognizer:tapGesture];
- (void) imageTapped:(UITapGestureRecognizer *)tapGesture {
MKAnnotationView * annotationView = (MKAnnotationView *)tapGesture.view.superview;
if (annotationView.selected) {
[annotationView setSelected:NO animated:YES];
} else {
[annotationView setSelected:YES animated:YES];
}
}
Вы можете использовать следующий метод расширения Swift, чтобы помочь. Самый популярный ответ приводит к размытому изображению с использованием связанной вспомогательной библиотеки.
extension UIImage {
func rotated(degrees degrees : Int) -> UIImage {
// calculate the size of the rotated view's containing box for our drawing space
let rotatedViewBox = UIView(frame: CGRectMake(0,0,self.size.width, self.size.height))
let rotation = CGFloat(degrees) * CGFloat(M_PI) / 180
let t = CGAffineTransformMakeRotation(rotation);
rotatedViewBox.transform = t;
let rotatedSize = rotatedViewBox.frame.size;
UIGraphicsBeginImageContextWithOptions(rotatedSize, false, 0.0);
let context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, rotatedSize.width/2, rotatedSize.height/2);
CGContextRotateCTM(context, rotation);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), self.CGImage);
let rotatedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return rotatedImage;
}
}
Использование:
annotationView.image = UIImage(named: "my_image")!.rotated(degrees: 45)
// Просто устанавливаем свойство изображения перед добавлением подпредставления, и оно работает как шарм
MKAnnotationView *aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Pin"];
UIImageView *iv = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"mapPin.png"]];
aView.image = [UIImage imageNamed:@"mapPin.png"]; // just this line
[aView addSubview:iv];
aView.canShowCallout = YES;