如何在对主视图应用变换后获取子视图的框架?

3

我创建了一个名为mainView的UIView对象,并在其上添加了一个子视图。 我对mainView应用了变换以减小帧大小。 但是,mainView的子视图框架没有缩小。 如何缩小此子视图的大小。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    CGFloat widthM=1200.0;
    CGFloat heightM=1800.0;
    UIView *mainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, widthM, heightM)];
    mainView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"te.png"]];
    [self.view addSubview:mainView];
    CGFloat yourDesiredWidth = 250.0;
    CGFloat yourDesiredHeight = yourDesiredWidth *heightM/widthM;
    CGAffineTransform scalingTransform;
    scalingTransform = CGAffineTransformMakeScale(yourDesiredWidth/mainView.frame.size.width, yourDesiredHeight/mainView.frame.size.height);
     mainView.transform = scalingTransform;
    mainView.center = self.view.center;
    NSLog(@"mainView:%@",mainView);
    UIView *subMainView= [[UIView alloc] initWithFrame:CGRectMake(100, 100, 1000, 1200)];
    subMainView.backgroundColor = [UIColor redColor];
    [mainView addSubview:subMainView];
    NSLog(@"subMainView:%@",subMainView);

}

这些视图的NSLog:

mainView:<UIView: 0x8878490; frame = (35 62.5; 250 375); transform = [0.208333, 0, 0, 0.208333, 0, 0]; layer = <CALayer: 0x8879140>>
subMainView:<UIView: 0x887b8c0; frame = (100 100; 1000 1200); layer = <CALayer: 0x887c160>>

这里mainView的宽度为250,subview的宽度为1000。但是当我在模拟器中输出时,subview被正确地占据了,但它没有跨越mainView。这怎么可能?如何在转换后相对于mainView帧获取subview的框架?

2个回答

9
您看到的是正常行为。一个UIView的框架是相对于其父视图而言的,因此当您对其父视图应用变换时,它不会改变。虽然视图也会出现“扭曲”,但框架不会反映这些变化,因为它仍然与其父视图保持相同的位置。
但是,我假设您想要获取相对于最顶层的UIView的视图框架。在这种情况下,UIKit提供了以下函数:
- [UIView convertPoint:toView:] - [UIView convertPoint:fromView:] - [UIView convertRect:toView:] - [UIView convertRect:fromView:]
我已经将这些应用到您的示例中:
CGRect frame = [[self view] convertRect:[subMainView frame] fromView:mainView];
NSLog(@"subMainView:%@", NSStringFromCGRect(frame));

这是输出结果:

subMainView:{{55.8333, 83.3333}, {208.333, 250}}

2
除了s1m0n的回答之外,将变换矩阵应用于视图的好处在于,您可以继续使用其原始坐标系进行推理(在您的情况下,您可以使用未转换的坐标系处理subMainView,这就是为什么即使subMainView的框架比mainView转换后的框架大,它仍然不会越过父视图,因为它会自动转换)。这意味着当您有一个经过变换的父视图(例如旋转和缩放)并且您想添加子视图到与该父视图的特定点相对应的位置时,您不必先跟踪先前的变换才能这样做。
如果您真的想知道子视图在变换后的坐标系中的框架,只需对子视图的矩形应用相同的变换即可:
CGRect transformedFrame = CGRectApplyAffineTransform(subMainView.frame, mainView.transform);

如果你使用 NSLog 输出这个 CGRect,你会得到以下结果:
Transformed frame: {{20.8333, 20.8333}, {208.333, 250}}

我相信这就是你所寻找的价值观。希望这能回答你的问题!


2
在回答这个问题的时候,iOS 7 刚刚发布,更不用说 iOS 8 了。那么你接下来要做什么呢?是要在 Java 问题的答案中留言说它在 C# 中行不通并将其踩到底吗? :) - micantox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接