Как повернуть CGRect или CGImageCreateWithImageInRect? - PullRequest
0 голосов
/ 15 января 2012

Чтобы описать мой проект:

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

//whenever the frame is moved, updated the CGRect frameRect and run this:

self.newCroppedImage = CGImageCreateWithImageInRect([bgImage.image CGImage], frameRect);
 frame.image = [UIImage imageWithCGImage:self.newCroppedImage];

Во всяком случае, у меня также есть распознаватель жестов вращения, который позволяет пользователю поворачивать кадр (и, соответственно, поворачивать изображение).Это связано с тем, что CGRect, отправленный в CGImageCreateWithImageInRect, по-прежнему ориентирован на исходное вращение.Это разрушает иллюзию, что вы смотрите через окно, потому что изображение, которое вы видите, поворачивается, когда только рамка должна отображаться таким образом.

Так что в идеале мне нужно взять поворот моей рамки и применить егоизображение, созданное из моего bgImage.У кого-нибудь есть какие-нибудь подсказки или идеи о том, как я могу применить это?

1 Ответ

4 голосов
/ 15 января 2012

Я предлагаю вам другой подход. Не создавайте постоянно новые изображения для добавления в UIImageView. Вместо этого настройте иерархию представления следующим образом:

White view
    "Hole" view (just a regular UIView)
        Image view

То есть белый вид имеет вид отверстия в качестве подпредставления. Вид с отверстием имеет UIImageView в качестве подпредставления.

Для вида отверстия должно быть установлено свойство clipsToBounds, установленное в YES (вы можете установить его с помощью кода или в своем кончике).

Размер изображения должен иметь размер, равный размеру его изображения. Это, конечно, будет больше, чем размер отверстия.

И это очень и очень важно: центр вида изображения должен быть установлен в центр вида отверстия.

Вот код, который я использовал в своем тестовом проекте для настройки. Белый вид self.view. Я начинаю с отверстия, центрированного на белом виде, и устанавливаю центр вида изображения в центр вида с отверстием.

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:YES];

    CGRect bounds = self.view.bounds;
    self.holeView.center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
    self.holeView.clipsToBounds = YES;

    bounds = self.holeView.bounds;
    self.imageView.center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
    self.imageView.bounds = (CGRect){ CGPointZero, self.imageView.image.size };

}

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

Для панорамирования и поворота отверстия я собираюсь установить holeView.transform. Я не собираюсь менять holeView.frame или holeView.center. У меня есть две переменные экземпляра, _holeOffset и _holeRotation, которые я использую для вычисления преобразования. Хитрость в том, чтобы сделать его похожим на дыру в белом виде, открывая вид изображения, - применить преобразование обратное к виду изображения, отменив эффекты преобразования вида дыр:

- (void)updateTransforms {
    CGAffineTransform holeTransform = CGAffineTransformIdentity;
    holeTransform = CGAffineTransformTranslate(holeTransform, _holeOffset.x, _holeOffset.y);
    holeTransform = CGAffineTransformRotate(holeTransform, _holeRotation);
    self.holeView.transform = holeTransform;
    self.imageView.transform = CGAffineTransformInvert(holeTransform);
}

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

Я поставил UIPanGestureRecognizer на holeView. Я настроил его для отправки panGesture: на мой контроллер вида:

- (IBAction)panGesture:(UIPanGestureRecognizer *)sender {
    CGPoint offset = [sender translationInView:self.view];
    [sender setTranslation:CGPointZero inView:self.view];
    _holeOffset.x += offset.x;
    _holeOffset.y += offset.y;
    [self updateTransforms];
}

Я также поставил UIRotationGestureRecognizer на holeView. Я настроил его для отправки rotationGesture: на мой контроллер вида:

- (IBAction)rotationGesture:(UIRotationGestureRecognizer *)sender {
    _holeRotation += sender.rotation;
    sender.rotation = 0;
    [self updateTransforms];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...