我有一个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
向上扩展太大,正如您在this ugly video中看到的那样。
答案 0 :(得分:6)
将第一个视图的bounds
,center
和transform
复制到第二个视图。
您的代码无效,因为frame
是派生自bounds
,center
和transform
的值。 frame
的setter尝试通过反转过程来做正确的事情,但是当设置了非身份transform
时,它无法始终正常工作。
documentation在这一点上非常明确:
如果transform属性不是identity变换,则此属性的值是未定义的,因此应该被忽略。
...
如果transform属性包含非标识变换,则frame属性的值是未定义的,不应修改。在这种情况下,您可以使用center属性重新定位视图,并使用bounds属性调整大小。
答案 1 :(得分:3)
假设viewA是第一个包含框架和视图的视图。转换,并且您希望将这些值传递给viewB。
因此,您需要获取 viewA的原始帧并在传递转换之前将其传递给viewB 。否则,当您添加变换时,viewB的帧将再次更改。
要获取原始帧,只需将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
之后,观看A& viewB将在superView上具有相同的UI。