UIScrollView ImageView с булавками сверху - PullRequest
11 голосов
/ 27 июня 2009

У меня есть 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];

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

Ответы [ 5 ]

9 голосов
/ 02 декабря 2011

Мне нравится ваша идея сохранить все контакты в представлении, предназначенном для контактов (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;

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

В вашем viewDidLoad MyViewController добавьте ваши виды выводов в качестве подпредставлений 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;
}
3 голосов
/ 28 июня 2009

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

Anchor a UIView

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

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

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

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

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

0 голосов
/ 01 февраля 2012

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

// [dropPinView.layer setAnchorPoint: CGPointMake (0.5, 1)];

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

0 голосов
/ 13 апреля 2010

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

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

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

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

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

шишка. ;)

0 голосов
/ 08 июля 2009

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

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

Барни

...