如何旋转CGRect或CGImageCreateWithImageInRect?

时间:2012-01-15 07:24:58

标签: iphone ios xcode ipad

描述我的项目:

我有一个漂浮在白色图层上的矩形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];

无论如何,我还有一个旋转手势识别器,允许用户旋转框架(并因此旋转图像)。这是因为发送到CGImageCreateWithImageInRect的CGRect仍然朝向其原始旋转。这打破了您通过窗口查看的错觉,因为只有框架应该以这种方式显示时,您看到的图像才会旋转。

理想情况下,我需要旋转框架并将其应用于从我的bgImage创建的图像。有没有人对我如何应用这个有任何线索或想法?

1 个答案:

答案 0 :(得分:4)

我建议你采取不同的方法。不要经常创建新图像以放入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.frameholeView.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];
}