在ios中,如果要比较两个uiview是否重叠,需要转换到统一坐标系进行比较。ios提供了如下api可以进行uiview的坐标转换
- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
举个具体的例子,某个页面布局如下图所示:
1、算出在红色控件里的蓝色控件在控制器view中的位置(其实就是算x和y的值,因为宽高不变)
CGRect newRect = [self.view convertRect:self.blueView.frame fromView:self.redView];
2、在蓝色控件中定义一个宽高各为100的正方形,相对于蓝色控件的坐标为(50, 50),算出这个正方形在绿色控件中的位置
CGRect newRect = [self.blueView convertRect:CGRectMake(50, 50, 100, 100) toView:self.greenView];
3、在蓝色控件中定义一个宽高各为100的正方形,相对于蓝色控件的坐标为(50, 50),算出这个正方形相对于window中的位置
CGRect newRect = [self.blueView convertRect:CGRectMake(50, 50, 100, 100) toView:nil];
toView后是可以传nil的,传nil就代表传的是window,上面的代码等等价于下面的代码
CGRect newRect = [self.blueView convertRect:CGRectMake(50, 50, 100, 100) toView:self.view.window];
4、以蓝色控件的坐标原点为原点,并且和蓝色控件一样大小(bounds)的图案在window中的位置
CGRect newRect = [self.blueView convertRect:self.blueView.bounds toView:nil];
等价于
CGRect newRect = [self.redView convertRect:self.blueView.frame toView:nil];
这样写也表明了frame和bounds的区别:frame表示的是在父控件中的位置和大小,bounds表示的是以自身为坐标原点的位置和大小。
等价于
CGRect newRect = [self.view.window convertRect:self.blueView.bounds fromView:self.blueView];
总结:
算出view在window中的位置
[self.superview convertRect:self.frame toView:nil]
等价于
[self.window convertRect:self.frame fromView:self.superview]
参考文章:
1、https://www.jianshu.com/p/1ae76c34a7da
2、https://www.jianshu.com/p/bd02e161772f