今天使用CGRectContainsRect方法时,出现了一些问题,现在总结一下:
首先了解一下一些基本的方法:
CGRectContainsRect(CGRect rect1, CGRect rect2) 判断rect1是否包含rect2
CGRectContainsPoint(CGRect rect, CGPoint point) 判断point是不是在rect上
CGRectIntersectsRect(CGRect rect1, CGRect rect2) 判断两个区域是否相交
CGRectIntersection (CGRect r1,CGRect r2); 两个矩形的相交的矩形区域
CGPointEqualToPoint(); 两个点是否是一个点
CGSizeEqualToSize(); 两个size是否一样
CGRectInset(CGRect rect, CGFloat dx, CGFloat dy) 根据一个矩形的中心点来创建矩形,正值是创建比较小的矩形,负值是创建比较大的矩形.
然后看 demo:
首先我通过storyboard给视图控制器的 view 添加3个 view, 如下图:
然后建立关联,分别得到对应的 view.然后并编写相应代码如下:
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *blueView;
@property (weak, nonatomic) IBOutlet UIView *redView;
@property (weak, nonatomic) IBOutlet UIView *yellowView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self test1];
}
-(void)test1{
if(CGRectIntersectsRect(self.redView.frame, self.blueView.frame)){
NSLog(@"红色视图与蓝色相交!");
}else{
NSLog(@"红色视图与蓝色视图不相交!");
}
if (CGRectContainsRect(self.redView.frame,self.blueView.frame)) {
NSLog(@"红色视图包含蓝色视图!");
}else{
NSLog(@"红色视图不包含蓝色视图!");
}
if (CGRectContainsRect(self.redView.frame,self.yellowView.frame)) {
NSLog(@"红色视图包含黄色视图!");
}else{
NSLog(@"红色视图不包含黄色视图!");
}
NSLog(@"%@ %@ %@",NSStringFromCGRect(self.redView.frame),NSStringFromCGRect(self.blueView.frame),NSStringFromCGRect(self.yellowView.frame));
}
@end
结果为:红色视图与蓝色相交! 红色视图不包含蓝色视图! 红色视图包含黄色视图!
{{36, 74}, {240, 260}} {{8, 8}, {120, 120}} {{112, 135}, {120, 120}}
一看结果,为什么啊!blueView和yellowView都是添加到redView上啊,怎么会一个包含,一个不包含啊!,但是不知道你有没有注意到打印出来的 frame有什么问题没?现在就进入主题了,UIView中的坐标转换.先看代码:
CGRect newFrame = [self.redView convertRect:self.blueView.frame toView:self.view];
NSLog(@"newFrame: %@",NSStringFromCGRect(newFrame));
if (CGRectContainsRect(self.redView.frame,newFrame)) {//必须确保有着相同的superview(其实也就是有着相同的坐标系)或者进行坐标系转换才能够正确使用该方法.
NSLog(@"红色视图包含蓝色视图!");
}else{
NSLog(@"红色视图不包含蓝色视图!");
}
结果为:红色视图包含蓝色视图! newFrame: {{44, 82}, {120, 120}}.
那么现在结果就对了,所以关键就在于视图相对的坐标系不一样.所以要把blueView变换到当前坐标系.
还记得刚学 frame 和 bounds的时候,由于UI控件的Frame属性都是依据该控件的父控件原点作为坐标系原点(0,0)的,所以,当父控件不是控制器view时,无法根据UI控件的frame来获取其相对于控制器view的位置。在实际开发中,为了获取某个子控件相对于屏幕顶部/底部/左边/右边的实际距离,必须要去改变子控件的坐标系。
以下是一些常用的转换方法:
将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view;
将像素point从view中转换到当前视图中,返回在当前视图中的像素值
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view;
将rect由rect所在视图转换到目标视图view中,返回在目标视图view中的rect
- (CGRect)convertRect:(CGRect)rect toView:(UIView *)view;
将rect从view中转换到当前视图中,返回在当前视图中的rect
- (CGRect)convertRect:(CGRect)rect fromView:(UIView *)view;
-
- 注:若view参数为空,则转换为窗口(window)的坐标系;接收者与view都必须是同一窗口(window)的对象。