Вращение отображаемого изображения 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;
Другие вопросы по тегам