iOS中將一個view的frame轉(zhuǎn)換為基于屏幕坐標的方法

一.官方sdk實現(xiàn)方法.

iOS中將一個view的frame轉(zhuǎn)換為基于屏幕坐標的方法,蘋果提供了一下sdk.

- (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;
image.png
image.png

官方sdk實現(xiàn)的時候,對于由哪個view調(diào)用方法,point參數(shù)需要傳入什么,view參數(shù)需要傳入什么很是費解.
看了官方的描述之后理解如下:

  • [receiver convertRect:rect toView:view];
    • 將一個從receiver的對應系統(tǒng)中的rect區(qū)域,轉(zhuǎn)換成為其他的view的坐標.
  • [receiver convertRect:rect fromView:view];
    • 將另外一個view的對應系統(tǒng)的rect區(qū)域,轉(zhuǎn)換成receiver的區(qū)域.

1.首先方法的調(diào)用者,叫做方法(消息)的接受者,receiver.
2.第一個參數(shù)rect應該是這個view自己內(nèi)部的一塊區(qū)域,這塊區(qū)域如果你想是view自己本身,那么就是用view.bounds,如果你想是他內(nèi)部的一塊空間,你可以自己指定.但是切忌使用self.frame,那么基本上算出來的就是錯誤的結果.
3.第三個參數(shù)是目標view,如果你想把view轉(zhuǎn)成receiver里面的坐標,請用- [receiver convertRect:rect fromView:view];
如果你想把view的坐標轉(zhuǎn)成reciever里面的坐標,請用- [receiver convertRect:rect toView:view];

舉個例子:把當前view的坐標轉(zhuǎn)換成window的坐標,就有一下兩種寫法:(傳入nil表示當前window)

CGRect frame2 = [view convertRect:view.bounds toView:nil];
CGRect frame3 = [[UIApplication sharedApplication].keyWindow convertRect:view.bounds fromView:view];

二.自己的遞歸實現(xiàn)

之前在需求中一直需要這個功能,針對于蘋果提供的sdk計算一直有問題,苦于對蘋果一下接口的不了解.實現(xiàn)了一個自己遞歸的實現(xiàn)版本.

/**
 *  計算一個view相對于屏幕的坐標
 */
- (CGRect)relativeFrameForScreenWithView
{
    UIView *view = self;
    CGFloat x = .0;
    CGFloat y = .0;
    while (view != [UIApplication sharedApplication].keyWindow && nil != view) {
        x += view.frame.origin.x;
        y += view.frame.origin.y;
        view = view.superview;
        if ([view isKindOfClass:[UIScrollView class]]) {
            x -= ((UIScrollView *) view).contentOffset.x;
            y -= ((UIScrollView *) view).contentOffset.y;
        }
    }
    return CGRectMake(x, y, self.frame.size.width, self.frame.size.height);
}

三.另外附上一個方法,計算當前view是否在屏幕內(nèi).


/**
 *  判斷View是否顯示在屏幕上
 */
- (BOOL)isDisplayedInScreen
{
    if (self == nil) {
        return NO;
    }
    CGRect screenRect = [UIScreen mainScreen].bounds;
    // 轉(zhuǎn)換view對應window的Rect
    CGRect rect = [self convertRect:self.bounds toView:nil];
    if (CGRectIsEmpty(rect) || CGRectIsNull(rect)) {
        return NO;
    }
    // 若view 隱藏
    if (self.hidden) {
        return NO;
    }
    // 若沒有superview
    if (self.superview == nil) {
        return NO;
    }
    // 若size為CGrectZero
    if (CGSizeEqualToSize(rect.size, CGSizeZero)) {
        return  NO;
    }
    // 獲取 該view與window 交叉的 Rect
    CGRect intersectionRect = CGRectIntersection(rect, screenRect);
    if (CGRectIsEmpty(intersectionRect) || CGRectIsNull(intersectionRect)) {
        return NO;
    }
    return YES;
}
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容