Вопрос

У меня есть UIScrollView который имеет UIImageView.Я хочу показать булавки на этом imageView.Когда я добавляю пины в качестве подвидов ImageView, все отлично, за исключением того, что при масштабировании преобразование масштаба происходит и на выводах.Я не хочу такого поведения и хочу, чтобы мои пин-коды оставались прежними.

Поэтому я решил добавить контакты в другой вид, который находится поверх ImageView и также является подвидом UIScrollView.Идея здесь, если вы можете себе представить, состоит в том, чтобы создать слой, который нависает над картой и не масштабируется, но показывает точки над тем местом, где я их наношу.

Пин-код при добавлении в вид слоя не разрушается, если ImageView весы.Однако затем проблема заключается в том, что положение выводов не соответствует исходному началу координат x / y, поскольку ImageView претерпел масштабное преобразование.

По сути, это пользовательская карта места с пинами.Я пытаюсь, чтобы пины перемещались, а не увеличивались и уменьшались по моему ImageView, но при этом помню, куда я их поместил, когда произойдет масштабирование.

Какой - то код:

scrollView = [[UIScrollView alloc] initWithFrame:viewRect];

scrollView.delegate = self;
scrollView.pagingEnabled = NO;
scrollView.scrollsToTop = NO;
[scrollView setBackgroundColor:[UIColor clearColor]];
scrollView.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView.bounces = YES;
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;

imageViewMap = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"]];

imageViewMap.userInteractionEnabled = YES;

viewRect = CGRectMake(0,0,imageViewMap.image.size.width,imageViewMap.image.size.height);

//viewRect = CGRectMake(0,0,2976,3928);

[scrollView addSubview:imageViewMap];

[scrollView setContentSize:CGSizeMake(viewRect.size.width, viewRect.size.height)];

iconsView = [[UIView alloc] initWithFrame:imageViewMap.frame];

[scrollView addSubview:iconsView];

Код для добавления PIN-кода позже при каком-либо событии.

[iconsView addSubview:pinIcon];

Я застрял в попытках выяснить, как заставить мои пины наводиться на карту, не перемещаясь при изменении масштаба.

Это было полезно?

Решение

Мне нравится ваша идея сохранить все пины в представлении, посвященном пинам (iconsView), но я решил просто добавить их как подвиды того, что вы назвали imageViewMap.

Импортируйте файл QuartzCore.framework в свой проект.

Назовите свой контроллер просмотра MyViewController.

#import <QuartzCore/QuartzCore.h>
@interface MyViewController : UIViewController <UIScrollViewDelegate>
@property (retain) UIScrollView *scrollView;
@property (retain) UIImageView *imageView;

// и так далее

@implementation MyViewController

@synthesize scrollView;
@synthesize imageView;

Я предположу, что у вас есть представление pin-кода или контроллер представления под названием DropPinViewController .Если вы просто используете изображение, это может быть UIImageView, но у моих пинов есть метки, поэтому я использовал xib.Булавка должна указывать на нижний центр xib, потому что мы собираемся поместить там точку привязки.

В вашем viewDidLoad вашего MyViewController добавьте ваши pin-представления в качестве вложенных представлений ImageView.Добавьте ImageView в качестве подвида к ScrollView.Установите размер содержимого ScrollView.

scrollView.delegate = self;

Используйте эти методы делегирования:

- (void)scrollViewDidZoom:(UIScrollView *)aScrollView
{   
    for (UIView *dropPinView in imageView.subviews) {       
    CGRect oldFrame = dropPinView.frame;
    // 0.5 means the anchor is centered on the x axis. 1 means the anchor is at the bottom of the view. If you comment out this line, the pin's center will stay where it is regardless of how much you zoom. I have it so that the bottom of the pin stays fixed. This should help user RomeoF.
   [dropPinView.layer setAnchorPoint:CGPointMake(0.5, 1)];
    dropPinView.frame = oldFrame;
    // When you zoom in on scrollView, it gets a larger zoom scale value.
    // You transform the pin by scaling it by the inverse of this value.
    dropPinView.transform = CGAffineTransformMakeScale(1.0/scrollView.zoomScale, 1.0/scrollView.zoomScale);
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return imageView;
}

Другие советы

Итак, одна вещь, которую я реализовал, которая не решила мою проблему, но я думаю, что это правильный путь, взята из этой статьи.

Закрепите пользовательский интерфейс

У меня есть иерархия представлений следующим образом.

UIScrollView
 - UIImageView (map image)
 - IconsView (layer image to hold icons)

Следующий шаг, который мне нужно решить, - это сохранить мои пин-коды, добавленные в IconsView закрепленный в том же месте , когда UIImageView увеличивается и уменьшается масштаб изображения.

У меня был цикл for, который проходил через все мои контакты, которые являются подвидами IconsView и обновили их Происхождение X и Y.Это было в UIScrollView делегаты scrollViewDidScroll способ.

Проблема заключалась в том, что этот метод имеет ужасную производительность на устройстве, так как при большом количестве контактов на карте требуется слишком много обработки.

Несколько рекомендаций:

1) Вы заметите в приложении Google Maps, что оно ограничивает количество пин-кодов, которые оно пытается отобразить по умолчанию.Он будет отображать только результаты, наиболее близкие к центральной точке, даже если существует больше возможных совпадений.

2) Вы могли бы ненадолго скрыть контакты во время любого действия прокрутки или зажима, чтобы интерфейс оставался отзывчивым, и перерисовать их в тот момент, когда изображение перестанет двигаться.

3) Если вам необходимо отобразить большое количество пинов и анимировать их, вы также можете рассмотреть возможность использования CABasicAnimations для одновременной анимации пинов и фона, изменяя положение пинов с использованием той же математики, которая преобразует масштаб фонов.Это могло бы сгладить отображение за счет более плавного распространения анимации и запуска ее на довольно низком уровне, но создает другие проблемы и ограничения.

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Animation_Types_Timing/Articles/PropertyAnimations.html#//apple_ref/doc/uid/TP40006672-SW1

Барни

У меня такая же проблема, и я нахожу идею ручного исправления местоположения pin-кода не очень привлекательной.Затем я скорее рисую свои пины на представлении, возвращаемом в функции делегирования viewForZoomingInScrollView: и обновите размер подвида (маркеров) после завершения масштабирования.

Тем не менее, меня раздражает, что это возможно в приложении Google Maps, но я не могу воссоздать его.

Еще одна вещь:Кто-нибудь может объяснить мне поведение exhibitet, когда я добавляю подвиды в UIScrollView, которые не являются 'viewForZoomingInScrollView' ..?Например:

UIImageView* marker = [[UIImageView alloc] initWithImage: myMarkerImage];
[marker setCenter: CGPointMake(250,150)];
[myScrollView addSubview: marker];

Кажется, это нормально работает для начального вида и при панорамировании.При масштабировании размер этих вложенных представлений не изменяется, к чему мы на самом деле и стремимся, но проблема в том, что начало кадра UIView перемещается по виду прокрутки каким-то довольно странным образом.Похоже, что если увеличить масштаб изображения, то marker.frame.size.origin всегда перемещается к верхнему левому углу (superview (0,0)), создавая впечатление, что мы на самом деле уменьшаем масштаб.Это тоже странно, потому что "центр масштабирования" всегда должен быть в центре экрана, не так ли?Ну, пока я этого не понимаю.

удар.;)

Спасибо Дэвиду Брауну.Ваш код работает, за исключением одной строки, которую мне пришлось закомментировать.Мой проект включал в себя UIScrollView, затем UIImageView сверху, который показывает карту, затем, наконец, контакты (кнопки), которые код позиционирует после обнаружения жеста двойного касания.Ваш код помог мне учесть масштаб масштабирования.Ограничение, однако, заключалось в том, что когда я зажимаю для увеличения, каждый вывод не "прилипает" к определенной части рисунка, к которой я дважды прикоснулся.Я наткнулся на решение, когда закомментировал эту строку:

//[dropPinView.layer setAnchorPoint:CGPointMake(0.5, 1)]установка точки привязки слоя:;

У меня нет полного понимания, но мой код теперь работает!Я надеюсь, что мой опыт принесет пользу другим.Спасибо, Дэвид!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top