У меня есть UIScrollView, у которого есть UIImageView. Я хочу показать булавки на этом imageView. Когда я добавляю булавки в качестве подвидов ImageView, все отлично, за исключением того, что когда вы увеличиваете масштаб, преобразование масштаба происходит и на булавках. Я не хочу такого поведения и хочу, чтобы мои контакты оставались прежними.
Поэтому я решил добавить пины в другое представление, которое находится поверх ImageView и также является подвидом представления UIScrollView. Идея здесь, если вы представляете, состоит в том, чтобы иметь слой, который нависает над картой и не масштабируется, но показывает булавки там, где я их рисую.
Булавка при добавлении в представление слоя не масштабируется, если масштабируется ImageView. Однако тогда проблема заключается в том, что положение штифтов не соответствует исходному началу x/y, поскольку ImageView имеет масштабное преобразование.
По сути, это пользовательская карта места с пинами. Я пытаюсь, чтобы булавки плавали, а не увеличивались и уменьшались над моим ImageView, но помню, где я их разместил, когда происходит увеличение.
Мне нравится ваша идея хранить все булавки в представлении, посвященном булавкам (iconsView), но я решил просто добавить их в качестве подвидов того, что вы назвали imageViewMap.
Импортируйте файл QuartzCore.framework в свой проект.
Назовите свой контроллер представления MyViewController.
Я предполагаю, что у вас есть вид булавки или контроллер представления под названием DropPinViewController. Если вы просто используете изображение, это может быть UIImageView, но у моих контактов есть метки, поэтому я использовал xib. Штифт должен указывать на нижний центр 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;
}
Ответ 2 · рейтинг 3 · Koppo
Итак, я реализовал одну вещь, которая не решила мою проблему, но я думаю, что это правильный путь из этой статьи.
У меня есть иерархия представлений следующим образом.
UIScrollView
- UIImageView (map image)
- IconsView (layer image to hold icons)
Следующий шаг, который мне нужно решить, - это оставить мои контакты, добавленные к IconsView, закрепленными в одном и том же месте, когда UIImageView увеличивается и уменьшается.
У меня был цикл for, который прошел через все мои контакты, которые являются подвидами IconsView, и обновил их Origin X и Y. Это было в методе scrollViewDidScroll делегатов UIScrollView.
Проблема заключалась в том, что этот метод имеет ужасную производительность на устройстве, поскольку, когда на карте много точек, требуется слишком много обработки.
Ответ 3 · Barney Mattox
Несколько рекомендаций:
1) Вы заметите в приложении Google Maps, что оно ограничивает количество контактов, которые оно пытается отобразить по умолчанию. Он будет отображать только результаты, наиболее близкие к центральной точке, даже если возможных совпадений больше.
2) Вы можете ненадолго скрыть булавки во время любого действия прокрутки или сжатия, чтобы интерфейс оставался отзывчивым, и перерисовывать их в тот момент, когда представление изображения перестает двигаться.
3) Если вам нужно отобразить большое количество булавок и анимировать их, вы также можете рассмотреть возможность использования CABasicAnimations для одновременной анимации булавок и фона, преобразования положения булавок с использованием той же математики, которая преобразует масштаб фона. Это может сгладить отображение за счет более плавного распространения анимации и запуска ее на довольно низком уровне, но создает другие проблемы и ограничения.
У меня та же проблема, и я нахожу идею ручного исправления положения булавки не очень красивой. Затем я скорее рисую свои булавки на представлении, возвращаемом функцией делегата viewForZoomingInScrollView:, и обновляю размер подпредставления (маркеров) после завершения масштабирования.
Однако меня раздражает, что это возможно в приложении Google Maps, но я не могу его воссоздать.
Еще одна вещь: может ли кто-нибудь объяснить мне поведение экспонента, когда я добавляю подвиды в UIScrollView, которые не являются "viewForZoomingInScrollView"..? Например:
Кажется, это отлично работает для начального просмотра и при панорамировании. При масштабировании размер этих подпредставлений не изменяется, к чему мы и стремимся, но проблема в том, что исходная точка кадра UIView перемещается по прокрутке каким-то довольно странным образом. Похоже, что если увеличить масштаб, marker.frame.size.origin всегда движется к верхнему левому углу (супервид (0,0)), создавая впечатление, что мы на самом деле уменьшаем масштаб. Это тоже странно, потому что "центр масштабирования" всегда должен быть в центре экрана, не так ли? Ну, я пока не понимаю.
удар. ;)
Ответ 5 · RomeoF
Спасибо Дэвиду Брауну. Ваш код работает, за исключением одной строки, которую мне пришлось закомментировать. Мой проект включал наличие UIScrollView, затем UIImageView сверху, который показывает карту, а затем, наконец, контакты (кнопки), которые код позиционирует после обнаружения жеста двойного нажатия. Ваш код помог мне учесть масштаб масштабирования. Однако ограничение заключалось в том, что, когда я щипал для увеличения, каждая булавка не "прилипала" к определенной части рисунка, где я дважды нажал. Я наткнулся на решение, когда закомментировал эту строку: