iOS判斷兩個控件是否有重疊

一、父控件相同的兩個控件的重疊判斷

圖中伐蒋,紅色的View與藍(lán)色的View擁有相同的父控件工三,都是控制器的View,即紅色的View與藍(lán)色的View都是以控制器的View的左上角為原點先鱼。這種情況下可以直接使用該方法判斷兩個控件之間是否有重疊俭正。

1.png

二、坐標(biāo)系轉(zhuǎn)換

如果是兩個控件不是處于相同的父控件焙畔。那么上面的判斷方法就行不通段审。比如以下情況:

2.png

所以在解決這種復(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)換例子

3.png

代碼示例

#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)。


4.png

代碼示例:

#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];
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市捐下,隨后出現(xiàn)的幾起案子账锹,更是在濱河造成了極大的恐慌萌业,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,222評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奸柬,死亡現(xiàn)場離奇詭異生年,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)廓奕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評論 3 385
  • 文/潘曉璐 我一進(jìn)店門抱婉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人桌粉,你說我怎么就攤上這事授段。” “怎么了番甩?”我有些...
    開封第一講書人閱讀 157,720評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長届搁。 經(jīng)常有香客問我缘薛,道長,這世上最難降的妖魔是什么卡睦? 我笑而不...
    開封第一講書人閱讀 56,568評論 1 284
  • 正文 為了忘掉前任宴胧,我火速辦了婚禮,結(jié)果婚禮上表锻,老公的妹妹穿的比我還像新娘恕齐。我一直安慰自己,他們只是感情好瞬逊,可當(dāng)我...
    茶點故事閱讀 65,696評論 6 386
  • 文/花漫 我一把揭開白布显歧。 她就那樣靜靜地躺著,像睡著了一般确镊。 火紅的嫁衣襯著肌膚如雪士骤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,879評論 1 290
  • 那天蕾域,我揣著相機(jī)與錄音拷肌,去河邊找鬼。 笑死旨巷,一個胖子當(dāng)著我的面吹牛巨缘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播采呐,決...
    沈念sama閱讀 39,028評論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼若锁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了斧吐?” 一聲冷哼從身側(cè)響起拴清,我...
    開封第一講書人閱讀 37,773評論 0 268
  • 序言:老撾萬榮一對情侶失蹤靶病,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后口予,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娄周,經(jīng)...
    沈念sama閱讀 44,220評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,550評論 2 327
  • 正文 我和宋清朗相戀三年沪停,在試婚紗的時候發(fā)現(xiàn)自己被綠了煤辨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,697評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡木张,死狀恐怖众辨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舷礼,我是刑警寧澤鹃彻,帶...
    沈念sama閱讀 34,360評論 4 332
  • 正文 年R本政府宣布,位于F島的核電站妻献,受9級特大地震影響蛛株,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜育拨,卻給世界環(huán)境...
    茶點故事閱讀 40,002評論 3 315
  • 文/蒙蒙 一谨履、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧熬丧,春花似錦笋粟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至闷畸,卻和暖如春吨艇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腾啥。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評論 1 266
  • 我被黑心中介騙來泰國打工东涡, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人倘待。 一個月前我還...
    沈念sama閱讀 46,433評論 2 360
  • 正文 我出身青樓疮跑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親凸舵。 傳聞我的和親對象是個殘疾皇子祖娘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,587評論 2 350

推薦閱讀更多精彩內(nèi)容