1

我有一个 UIView,它可能应用了缩放和/或旋转变换。我的控制器创建一个新控制器并将视图传递给它。新控制器创建一个新视图并尝试将其放置在与传递的视图相同的位置和旋转中。它通过转换原始视图的框架来设置位置和大小:

CGRect frame = [self.view convertRect:fromView.frame fromView:fromView.superview];
ImageScrollView *isv = [[ImageScrollView alloc]initWithFrame:frame image:image];

这很好用,完美复制了缩放的大小和位置。但是,如果对 应用了旋转变换fromView,则它不会传输。

所以我添加了这一行:

isv.transform = fromView.transform;

这很好地处理了旋转以及缩放变换。结果是缩放变换有效地应用了两次,因此结果视图太大了。

那么如何在不加倍比例的情况下将位置(原点)、比例旋转从一个视图转移到另一个视图?


编辑

这是一个更完整的代码示例,其中原始 UIImageView ( fromView) 用于调整 UIScrollView(ImageScrollView 子类)的大小和位置:

CGRect frame = [self.view convertRect:fromView.frame fromView:fromView.superview];
frame.origin.y += pagingScrollView.frame.origin.y;
ImageScrollView *isv = [[ImageScrollView alloc]initWithFrame:frame image:image];
isv.layer.anchorPoint = fromView.layer.anchorPoint;
isv.transform = fromView.transform;
isv.bounds = fromView.bounds;
isv.center = [self.view convertPoint:fromView.center fromView:fromView.superview];
[self.view insertSubview:isv belowSubview:captionView];

这是 ImageScrollView 中的全部配置:

- (id)initWithFrame:(CGRect)frame image:(UIImage *)image {
    if (self = [self initWithFrame:frame]) {
        CGRect rect = CGRectMake(0, 0, frame.size.width, frame.size.height);
        imageLoaded = YES;
        imageView = [[UIImageView alloc] initWithImage:image];
        imageView.frame = rect;
        imageView.contentMode   = UIViewContentModeScaleAspectFill;
        imageView.clipsToBounds = YES;
        [self addSubview:imageView];
    }
    return self;
}

正如您在这个丑陋的视频中看到的那样,看起来好像变换导致imageView放大了太大。

4

2 回答 2

7

将第一个视图的boundscenter和复制transform到第二个视图。

您的代码不起作用,因为它frame、和. setter尝试通过反转过程来做正确的事情,但是当设置非身份时,它不能总是正确工作。boundscentertransformframetransform

文档在这一点上非常清楚:

如果变换属性不是恒等变换,则该属性的值是未定义的,因此应该被忽略。

...

如果 transform 属性包含非恒等变换,则 frame 属性的值未定义且不应修改。在这种情况下,您可以使用 center 属性重新定位视图并使用 bounds 属性调整大小。

于 2012-04-18T07:17:00.923 回答
3

假设 viewA 是包含框架和变换的第一个视图,并且您希望将这些值传递给 viewB。

因此,您需要在通过 transform 之前获取 viewA 的原始帧并将其传递给 viewB。否则,当您添加变换时,viewB 的框架将再更改 1 次。

要获取原始帧,只需将 viewA.transform 转换为CGAffineTransformIdentity

这是代码

CGAffineTransform originalTransform = viewA.transform; // Remember old transform
viewA.transform = CGAffineTransformIdentity; // Remove transform so that you can get original frame
viewB.frame = viewA.frame; // Pass originalFrame into viewB
viewA.transform = originalTransform; // Restore transform into viewA
viewB.transform = originalTransform; // At this step, transform will change frame and make it the same with viewA

之后,viewA 和 viewB 将在 superView 上具有相同的 UI。

于 2015-03-30T03:48:25.870 回答