Как скопировать изображение внутри UIImageView?

У меня есть UIImageView, который показывает изображение, которое шире и выше, чем UIImageView. Я хотел бы панорамировать изображение в представлении, используя анимацию (чтобы панорама была приятной и гладкой).

Мне кажется, что я должен просто настроить bounds.origin для UIImageView, и изображение должно перемещаться (потому что изображение должно рисовать внутри представления с помощью его происхождение, правильно?), но это, похоже, не работает. bounds.origin изменяется, но изображение рисуется в том же месте.

Что почти работает, это изменить contentsRect слоя вида. Но это начинается как единичный квадрат, хотя видимая область изображения - это не весь образ. Поэтому я не уверен, как бы я обнаружил, что край изображения потянут в область видимости (чего мне нужно избегать, поскольку она отображается, растягивая край до бесконечности, который выглядит, ну, под-пар).

У моего представления в настоящее время его contentsGravity установлен на kCAGravityTopLeft через Interface Builder, если это имеет значение (это заставляет изображение перемещаться?). Однако никаких других вариантов не было лучше.

UPDATE: чтобы быть ясным, я хочу перемещать изображение внутри, сохраняя представление в том же месте.

Ответ 1

Брэд Ларсон указал мне по правильной дороге, предложив поставить UIImageView внутри UIScrollView.

В конце я положил UIImageView внутри UIScrollView и установил для scrollView contentSize и границы imageView того же размера, что и изображение в UIImage

UIImage* image = imageView.image;
imageView.bounds = CGRectMake(0, 0, image.size.width, image.size.height);
scrollView.contentSize = image.size;

Затем я могу анимировать scrollView contentOffset, чтобы добиться приятного эффекта панорамирования:

[UIView beginAnimations:@"pan" context:nil];
[UIView setAnimationDuration:animationDuration];
scrollView.contentOffset = newRect.origin;
[UIView commitAnimations];

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

UIImage* image = imageView.image;

float xNewOrigin = [TCBRandom randomIntLessThan:image.size.width - scrollView.bounds.size.width];
float yNewOrigin = [TCBRandom randomIntLessThan:image.size.height - scrollView.bounds.size.height];

CGRect oldRect = scrollView.bounds;
CGRect newRect = CGRectMake(
    xNewOrigin,
    yNewOrigin, 
    scrollView.bounds.size.width,
    scrollView.bounds.size.height);

float xDistance = fabs(xNewOrigin - oldRect.origin.x);
float yDistance = fabs(yNewOrigin - oldRect.origin.y);
float hDistance = sqrtf(powf(xDistance, 2) + powf(yDistance, 2));
float hDistanceInPixels = hDistance;

float animationDuration = hDistanceInPixels / speedInPixelsPerSecond;

Я использую speedInPixelsPerSecond из 10.0f, но другие приложения могут захотеть использовать другое значение.

Ответ 2

Я настоятельно рекомендую включить UIImageView в UIScrollView. Отобразите UIImageView полное изображение и установите для параметра contentSize на UIScrollView то же самое, что и ваш размер UIImageView's. Ваш window в изображение будет размером UIScrollView, а с помощью scrollRectToVisible:animated: вы можете перемещаться по определенным областям на изображении анимированным образом.

Если вы не хотите, чтобы полосы прокрутки отображались, вы можете установить для свойств showsHorizontalScrollIndicator и showsVerticalScrollIndicator значение NO.

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