1.坐標系轉(zhuǎn)換convertPoint
對于復(fù)雜界面,適當(dāng)?shù)脑黾咏缑娴膶蛹売兄诤喕繉拥倪壿嫿Y(jié)構(gòu)浅蚪,更利于解耦藕帜。但是會遇到不同層級之間的view進行范圍判斷的問題,由于view所在的層級不同惜傲,直接去比較坐標是沒有意義的洽故,只有把需要判斷的view放置到同一個坐標系下,其坐標的判斷才有可比性盗誊。
下面通過一個例子說明
view層級結(jié)構(gòu)如上圖时甚,blueView和grayView是同一個層級,redView為grayView的子視圖哈踱,如何判斷redView和blueView的關(guān)系呢(在內(nèi)部荒适,在外部,還是相交)开镣?
此時就需要進行坐標系轉(zhuǎn)換
官方提供了4個方法(UIView的方法):
- -(CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;//點轉(zhuǎn)換
- -(CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;//點轉(zhuǎn)換
- -(CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;//矩形轉(zhuǎn)換
- -(CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;//矩形轉(zhuǎn)換
具體使用如下:
獲取redView
在self.view
坐標系中的坐標(以下兩種寫法等效):
CGPoint redCenterInView = [self.grayView convertPoint:self.redView.center toView:self.view];
CGPoint redCenterInView = [self.view convertPoint:self.redView.center fromView:self.grayView];
使用注意:
1.使用convertPoint:toView:
時刀诬,調(diào)用者應(yīng)為covertPoint的父視圖。即調(diào)用者應(yīng)為point的父控件邪财。toView即為需要轉(zhuǎn)換到的視圖坐標系舅列,以此視圖的左上角為(0,0)點卧蜓。
2.使用convertPoint:fromView:
時正好相反帐要,調(diào)用者為需要轉(zhuǎn)換到的視圖坐標系。fromView為point所在的父控件弥奸。
3.toView
可以為nil榨惠。此時相當(dāng)于toView傳入self.view.window
補充:有人問道為什么相對于self.view 和相對于self.view.window 不一樣呢?
因為在viewDidLoad
方法中盛霎,self.view.window為nil赠橙,測試的時候注意不要直接寫在viewDidLoad
方法中,寫在viewdidAppear
中愤炸。
--
2.點在范圍內(nèi)的判斷
方案一: 轉(zhuǎn)換為同一坐標系下后比較x期揪,y值,判斷范圍规个。
方案二: 利用pointInside方法進行判斷凤薛。
方案一不需介紹姓建,下面說明下方案二的使用。
UIView有如下一個方法缤苫,用于判斷點是否在內(nèi)部
- -(BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event; // default returns YES if point is in bounds
使用注意:
point必須為調(diào)用者的坐標系速兔,即調(diào)用者的左上角為(0,0)的坐標系活玲。
比如確定redView的中心點是否在blueView上:
//轉(zhuǎn)換為blueView坐標系點
CGPoint redCenterInBlueView = [self.grayView convertPoint:self.redView.center toView:self.blueView];
BOOL isInside = [self.blueView pointInside:redCenterInBlueView withEvent:nil];
NSLog(@"%d",isInside);
輸出結(jié)果為1涣狗。即點在范圍內(nèi)。
理解了這兩個方法舒憾,在做某些需求的時候就會更加得心應(yīng)手镀钓。