一、父控件相同的兩個控件的重疊判斷
圖中伐蒋,紅色的View與藍(lán)色的View擁有相同的父控件工三,都是控制器的View,即紅色的View與藍(lán)色的View都是以控制器的View的左上角為原點先鱼。這種情況下可以直接使用該方法判斷兩個控件之間是否有重疊俭正。
二、坐標(biāo)系轉(zhuǎn)換
如果是兩個控件不是處于相同的父控件焙畔。那么上面的判斷方法就行不通段审。比如以下情況:
所以在解決這種復(fù)雜的判斷就需要用到坐標(biāo)系轉(zhuǎn)換。
解決思路:將白色框與綠色框的坐標(biāo)系轉(zhuǎn)換為 window (控制器的View)的左上角為坐標(biāo)原點闹蒜。再使用上方判斷兩個控件是否有重疊的方法實現(xiàn)寺枉。所以先了解一下如何進(jìn)行坐標(biāo)系轉(zhuǎn)換。
坐標(biāo)系一個簡單的轉(zhuǎn)換例子
代碼示例
#import "ViewController.h"
@interface ViewController ()
/** 紅色的View */
@property (weak, nonatomic) IBOutlet UIView *redView;
/** 藍(lán)色的View */
@property (weak, nonatomic) IBOutlet UIView *blueView;
/** 綠色的View */
@property (weak, nonatomic) IBOutlet UIView *greenView;
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 讓綠色這個矩形框绷落,從以藍(lán)色框左上角為原點的坐標(biāo)系轉(zhuǎn)換到以紅色框左上角為坐標(biāo)系
CGRect newRect = [self.blueView convertRect:self.greenView.frame toView:self.redView];
// 還有個方法:讓綠色這個矩形框姥闪,從以藍(lán)色框左上角為原點的坐標(biāo)系轉(zhuǎn)換為以紅色框左上角為坐標(biāo)系
// CGRect newRect = [self.redView convertRect:self.greenView.frame fromView:self.blueView];
NSLog(@"綠色框以藍(lán)色框為原點的坐標(biāo)系:%@", NSStringFromCGRect(self.greenView.frame));
NSLog(@"綠色框轉(zhuǎn)換以紅色框為原點的坐標(biāo)系%@", NSStringFromCGRect(newRect));
// 輸出:
// 綠色框以藍(lán)色框為原點的坐標(biāo)系:{{50, 50}, {50, 50}}
// 綠色框轉(zhuǎn)換以紅色框為原點的坐標(biāo)系{{200, 100}, {50, 50}}
}
@end
三、不同父控件的兩個控件的重疊判斷
那么前面的比較復(fù)雜的也可以實現(xiàn)砌烁。將白色框與綠色框的坐標(biāo)系轉(zhuǎn)換為 window (控制器的View)的左上角為坐標(biāo)原點筐喳。再使用上方判斷兩個控件是否有重疊的方法實現(xiàn)。
代碼示例:
#import "ViewController.h"
@interface ViewController ()
/** 白色的View */
@property (weak, nonatomic) IBOutlet UIView *whiteView;
/** 綠色的View */
@property (weak, nonatomic) IBOutlet UIView *greenView;
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 讓綠色這個矩形框函喉,從以藍(lán)色框左上角為原點的坐標(biāo)系轉(zhuǎn)換到以紅色框左上角為坐標(biāo)系
CGRect whiteRect = [self.whiteView convertRect:self.whiteView.bounds toView:[UIApplication sharedApplication].keyWindow];
// toView:nil 寫 nil 默認(rèn)就表示 window
CGRect greenRect = [self.greenView convertRect:self.greenView.bounds toView:nil];
NSLog(@"綠色框以Window為原點的坐標(biāo)系:%@", NSStringFromCGRect(greenRect));
NSLog(@"白色框以Window為原點的坐標(biāo)系:%@", NSStringFromCGRect(whiteRect));
NSLog(@"%zd", CGRectIntersectsRect(whiteRect, greenRect));
// 輸出:
// 綠色框以Window為原點的坐標(biāo)系:{{187, 124}, {101, 64}}
// 白色框以Window為原點的坐標(biāo)系:{{99, 171}, {113, 91}}
// 1 ----> 表示重疊了
}
@end
四避归、總結(jié)
矩形框比較的2個函數(shù)
bool CGRectContainsRect(CGRect rect1, CGRect rect2)
判斷rect1是否包含了rect2
bool CGRectIntersectsRect(CGRect rect1, CGRect rect2)
判斷rect1和rect2是否有重疊
`注意:rect1和rect2要在同一個坐標(biāo)系,比較結(jié)果才準(zhǔn)確
轉(zhuǎn)換坐標(biāo)系總結(jié)
view2坐標(biāo)系 : 以view2的左上角為坐標(biāo)原點
view1坐標(biāo)系 : 以view1的左上角為坐標(biāo)原點
CGRect newRect = [view1 convertRect:rect fromView:view2];
// 讓rect這個矩形框管呵, 從view2坐標(biāo)系轉(zhuǎn)換到view1坐標(biāo)系, 得出一個新的矩形框newRect
// rect和view2的含義 : 用來確定矩形框原來在哪
CGRect newRect = [view1 convertRect:rect toView:view2];
// 讓rect這個矩形框梳毙, 從view1坐標(biāo)系轉(zhuǎn)換到view2坐標(biāo)系, 得出一個新的矩形框newRect
// rect和view1的含義 :用來確定矩形框原來在哪
獲得一個控件在window中的位置和尺寸
以獲得redView在window中的位置和尺寸為例
CGRect newRect = [[UIApplication sharedApplication].keyWindow convertRect:redView.bounds fromView:redView];
CGRect newRect = [[UIApplication sharedApplication].keyWindow convertRect:redView.frame fromView:redView.superview];
CGRect newRect = [redView convertRect:redView.bounds toView:[UIApplication sharedApplication].keyWindow];
CGRect newRect = [redView.superview convertRect:redView.frame toView:[UIApplication sharedApplication].keyWindow];
CGRect newRect = [redView convertRect:redView.bounds toView:nil];
CGRect newRect = [redView.superview convertRect:redView.frame toView:nil];