UIKit提供了一下幾種坐標(biāo)轉(zhuǎn)換的方法:
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;
- (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;
- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
用了好久囱井,一直沒發(fā)現(xiàn)轉(zhuǎn)換的規(guī)律趣避,今天嘗試總結(jié)一下轉(zhuǎn)換的坐標(biāo)值是如何得到的,上測試代碼:
UIView *fromView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 200,300)];
CGPoint point = CGPointMake(40, 30);
UIView *toView = [[UIView alloc] initWithFrame:CGRectMake(0, 64, 50, 50)];
fromView.bounds = (CGRect){CGPointMake(5, 10), fromView.frame.size};
toView.bounds = (CGRect){CGPointMake(15, 5), toView.frame.size};
CGPoint result = CGPointZero;
先說 convertPoint: toView:
result = [fromView convertPoint:point toView:toView];
NSLog(@"[result:%@]", NSStringFromCGPoint(result));
[fromView addSubview:toView];
result = [fromView convertPoint:point toView:toView];
NSLog(@"[result:%@]", NSStringFromCGPoint(result));
[toView removeFromSuperview];
[toView addSubview:fromView];
result = [fromView convertPoint:point toView:toView];
NSLog(@"[result:%@]", NSStringFromCGPoint(result));
輸出結(jié)果:
2017-01-16 22:55:55.013 Test[47145:1558803] [result:{60, -29}]
2017-01-16 22:55:55.013 Test[47145:1558803] [result:{55, -29}]
2017-01-16 22:55:55.014 Test[47145:1558803] [result:{45, 30}]
再看 convertPoint: fromView:住练,將上面的代碼替換為下面這段:
result = [toView convertPoint:point fromView:fromView];
NSLog(@"[result:%@]", NSStringFromCGPoint(result));
[fromView addSubview:toView];
result = [toView convertPoint:point fromView:fromView];
NSLog(@"[result:%@]", NSStringFromCGPoint(result));
[toView removeFromSuperview];
[toView addSubview:fromView];
result = [toView convertPoint:point fromView:fromView];
NSLog(@"[result:%@]", NSStringFromCGPoint(result));
輸出結(jié)果:
2017-01-16 23:16:39.167 Test[50726:1630406] [result:{60, -29}]
2017-01-16 23:16:39.167 Test[50726:1630406] [result:{55, -29}]
2017-01-16 23:16:39.168 Test[50726:1630406] [result:{45, 30}]
解釋一下上面代碼的含義:
[fromView convertPoint:point toView:toView];
[toView convertPoint:point fromView:fromView];
這兩句代碼的意思都是將fromView中的點p(40,30)轉(zhuǎn)換為相對toView的坐標(biāo)讲逛×氩海可以看到兩段代碼的結(jié)果是一樣的。
根據(jù)上面的結(jié)果可以總結(jié)出下面的計算公式:
[fromView convertPoint:point toView:toView];
[toView convertPoint:point fromView:fromView];
==> result = (fromView.frame.origin - fromView.bounds.origin) + point - (toView.frame.origin - toView.bounds.origin)
注意:
1许赃、如果view的bounds的origin不為(0,0)時馆类,view的子視圖會有一個對應(yīng)的偏移,因此計算的時候要減掉乾巧。
2、如果fromView藤滥、toView的任何一個為另一個的superView時社裆,該view不再參與計算。即:
(1)
[fromView addSubview:toView]; //即fromView為superView時
==> result = point - (toView.frame.origin - toView.bounds.origin)
(2)
[toView addSubview:fromView]; //即toView為superView時
==> result = (fromView.frame.origin - fromView.bounds.origin) + point
3、以上代碼只為找出iOS中坐標(biāo)轉(zhuǎn)換規(guī)律榄攀,不可死記硬背金句,理解最重要。