zoukankan      html  css  js  c++  java
  • ios开发之坐标系转换

    1:坐标系转换最核心的问题就是:比较两个坐标是否包含,或者是重叠等,最主要的问题是先将两个坐标转换到同一个坐标系下再去比较。第一步先确定矩形框在某个view坐标系下的frame(该矩形框是以该view的左上角为坐标原点)2:再转换到另一个view坐标系下(转换后的坐标依然是以另一个view的坐标原点来计算得出新坐标系下的矩形框)

    2:坐标系的转化方法:1:CGRectContainsRect(<#CGRect rect1#>, <#CGRect rect2#>),判断rect1矩形框是否包含rect2矩形框  2:CGRectIntersectsRect(<#CGRect rect1#>, <#CGRect rect2#>):判断rect1的矩形框是否和rect2的矩形框重叠 3:

    CGRectContainsPoint(<#CGRect rect#>, <#CGPoint point#>) ,判断某个点是否包含在矩形框内,4:以上三个方法的使用前提是都要在同一个坐标系下来判断,若不是在同一个坐标系下,利用坐标系转换转到同一个坐标系下,在进行比较。

    #import "ViewController.h"
    
    @interface ViewController ()
    /** 蓝色 */
    @property (nonatomic, weak) UIView *blueView;
    /** 橙色 */
    @property (nonatomic, weak) UIView *orangeView;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        UIView *blueView = [[UIView alloc] init];
        blueView.backgroundColor = [UIColor blueColor];
        blueView.frame = CGRectMake(50, 50, 100, 100);
        blueView.alpha = 0.5;
        [self.view addSubview:blueView];
        self.blueView = blueView;
        
        UIView *orangeView = [[UIView alloc] init];
        orangeView.backgroundColor = [UIColor orangeColor];
        orangeView.frame = CGRectMake(100, 100, 100, 100);
        orangeView.alpha = 0.5;
        [self.view addSubview:orangeView];
        self.orangeView = orangeView;
        
        // CGRectContainsRect(<#CGRect rect1#>, <#CGRect rect2#>)
        // CGRectIntersectsRect(<#CGRect rect1#>, <#CGRect rect2#>)
        //CGRectContainsPoint(<#CGRect rect#>, <#CGPoint point#>)
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        // self.blueView.bounds = {0, 0, 100, 100}
        // self.orangeView.bounds = {0, 0, 100, 100}
        
        // self.blueView.frame = {50, 50, 100, 100}
        // self.orangeView.frame = {200, 200, 100, 100}
        
        NSLog(@"%zd", CGRectIntersectsRect(self.blueView.frame, self.orangeView.frame));
    }
    
    @end

    总结:1:上部分代码两个view是在同一个坐标系下,都是以屏幕左上角为坐标原点,所以调用方法可以判断两个view是否是包含关系或是重叠关系  2:注意点:在touchBeagn方法的打印中,判断两个view是否是重叠关系,传入两个view的rect值,注意此时的rect值不能传入bounds,只能传入frame,因为两者需要在同一个坐标系下作比较,两者的父控件都是self.view,所以两者的frame都是以父控件的坐标原点计算的frame,而bounds确是以自身控件的原点计算的frame。所以用bounds两者根本不在同一个坐标下,所以只能传入frame

    3:坐标系的相互转换:不同坐标系转换到同一个坐标系下,进行比较:其中最核心的关键点是:1:要将不同坐标下的矩形框转换到统一坐标系下进行比较  2:第一步先要确定出矩形框在原坐标系下的frame,只有确定了矩形框在原来坐标系下的位置,才能准确转换到另一个坐标系中得到新的rect值   3:可以调用方法from,或是to方法进行坐标系的转换[view1 convertRect:rect fromView:view2];[view1 convertRect:rect toView:view2];其中无论是新转换的rect还是待转换的rect,都是以view1或是view2的左上角为坐标原点计算的

     view2坐标系 : 以view2的左上角为坐标原点

     view1坐标系 : 以view1的左上角为坐标原点

     CGRect newRect = [view1 convertRect:rect fromView:view2];

     让rect这个矩形框, 从view2坐标系转换到view1坐标系, 得出一个新的矩形框newRect

     rect和view2的含义 : 用来确定矩形框原来在哪

     CGRect newRect = [view1 convertRect:rect toView:view2];

     让rect这个矩形框, 从view1坐标系转换到view2坐标系, 得出一个新的矩形框newRect

     rect和view1的含义 :用来确定矩形框原来在哪

    #import "ViewController3.h"
    
    @interface ViewController3 ()
    @property (weak, nonatomic) IBOutlet UIView *blueView;
    @property (weak, nonatomic) IBOutlet UIView *redView;
    @end
    
    @implementation ViewController3
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //    view2坐标系 : 以view2的左上角为坐标原点
    //    view1坐标系 : 以view1的左上角为坐标原点
    //
    //    CGRect newRect = [view1 convertRect:rect fromView:view2];
    //    让rect这个矩形框, 从view2坐标系转换到view1坐标系, 得出一个新的矩形框newRect
    //    rect和view2的含义 : 用来确定矩形框原来在哪
    //
    //    CGRect newRect = [view1 convertRect:rect toView:view2];
    //    让rect这个矩形框, 从view1坐标系转换到view2坐标系, 得出一个新的矩形框newRect
    //    rect和view1的含义 :用来确定矩形框原来在哪
        
        // 确定redView在window中的位置和尺寸
    //    CGRect newRect = [self.redView convertRect:self.redView.bounds toView:[UIApplication sharedApplication].keyWindow];
    //    CGRect newRect = [self.redView.superview convertRect:self.redView.frame toView:[UIApplication sharedApplication].keyWindow];
        CGRect newRect = [self.redView convertRect:self.redView.bounds toView:nil];
    //    CGRect newRect = [self.redView.superview convertRect:self.redView.frame toView:nil];
    //    CGRect newRect = [[UIApplication sharedApplication].keyWindow convertRect:self.redView.bounds fromView:self.redView];
    //    CGRect newRect = [[UIApplication sharedApplication].keyWindow convertRect:self.redView.frame fromView:self.redView.superview];
        NSLog(@"%@", NSStringFromCGRect(newRect));
    }
    
    @end

    总结:1:坐标系的换换用to方法:1:当利用此方法做坐标系的转换时,toView的参数传空值nil的时候,默认为当前的主窗口。2:当做不同坐标系的相互转换的时候,利用bounds和frame都可以,主要是通过bounds或是frame来确定待矩形框在原view的位置,还要是确定了位置就可以实现不同坐标系下的转换。bounds是以自身view为坐标原点来确定矩形框的位置,传入的参数为自身的view和bounds,而frame是以其父控件的左上角为坐标原点,传入的参数为父控件的view和矩形框的frame。3:要想拿到某个控件的父控件,就是superView,self.redView.superview

        // 确定redView在window中的位置和尺寸

       CGRect newRect = [self.redView convertRect:self.redView.bounds toView:[UIApplication sharedApplication].keyWindow];

       CGRect newRect = [self.redView convertRect:self.redView.bounds toView:nil];

        CGRect newRect = [self.redView.superview convertRect:self.redView.frame toView:[UIApplication sharedApplication].keyWindow];

     CGRect newRect = [self.redView.superview convertRect:self.redView.frame toView:nil];

     4:判断在不同坐标下的两个矩形框是否包含关系或者是否是重叠关系:1:首先将两个处在不同坐标系下的矩形框转换到同一个坐标系在 2:在调用包含,重叠的方法,会返回一个Bool类型的返回值,来判断两个矩形框的关系

    #import "ViewController2.h"
    
    @interface ViewController2 ()
    @property (weak, nonatomic) IBOutlet UIView *greenView;
    @property (weak, nonatomic) IBOutlet UIView *whiteView;
    @end
    
    @implementation ViewController2
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        // CGPoint point = [self.whiteView convertPoint:CGPointMake(50, 50) fromView:self.greenView];
        // NSLog(@"%@", NSStringFromCGPoint(point));
        
        CGRect whiteRect = [self.whiteView convertRect:self.whiteView.bounds toView:nil];
        CGRect greenRect = [self.greenView convertRect:self.greenView.bounds toView:nil];
        
        NSLog(@"greenView - %@", NSStringFromCGRect(greenRect));
        NSLog(@"whiteView - %@", NSStringFromCGRect(whiteRect));
        NSLog(@"%zd", CGRectIntersectsRect(greenRect, whiteRect));
        
    }
    
    
    - (void)test
    {
        
        NSLog(@"greenView - %@", NSStringFromCGRect(self.greenView.frame));
        NSLog(@"whiteView - %@", NSStringFromCGRect(self.whiteView.frame));
        
        // greenView - {{10, 10}, {80, 80}}
        
        // whiteView - {{150, 150}, {80, 80}}
        
        NSLog(@"%zd", CGRectIntersectsRect(self.greenView.frame, self.whiteView.frame));
    }
    
    @end
  • 相关阅读:
    工资调整
    演义群侠传(八)【bloom组件源码学习】
    Win8快捷键
    教育类app
    演义群侠传(八)【我需要学习的东西】
    演义群侠传(七)【GC垃圾回收】
    演义群侠传(十)【重学设计模式】
    addChild&&rawChildren的addChild
    演义群侠传(六)【PSD切图方式】
    linux分析网卡流量
  • 原文地址:https://www.cnblogs.com/cqb-learner/p/5801997.html
Copyright © 2011-2022 走看看