当前位置: 首页 > news >正文

iOS开发中获取视图在屏幕上显示的位置

在iOS开发中,我们会经常遇到一个问题,例如,点击一个按钮,弹出一个遮罩层,上面显示一个弹框,弹框显示的位置在按钮附近。如果这个按钮的位置相对于屏幕边缘的距离是固定的,那就容易了,可以直接写死位置。可是,如果按钮是在UITableView的cell上呢?随着UITableView的滚动,按钮可能在顶部,也可能在底部,还可能在中间,左侧、右侧都有可能,那么,这个时候,怎么去计算按钮所在的位置呢?如果按钮所在的UITabelView是在另外一个UIScrollView的一个cell上呢?如果外面再有一个滚动层呢?这种布局确实很复杂。

最近公司的项目中有一个需求,所使用的层级就是一个UITableView中嵌套了一个UITableView和一个UICollectionView,而且还有一个点击按钮,效果就类似于头条资讯列表的小叉号,点击在按钮旁边弹出一个视图,对资讯进行屏蔽等操作。我在点击按钮的时候弹出一个顶级的遮罩层,在遮罩上面增加了一个操作的区域,但是,操作区域的位置需要根据按钮的位置进行确定,所以,花了点时间写了个方法,用来找到按钮在屏幕上的位置,相对于屏幕来说的;

其实代码并不多,只需要写一个UIView的扩展方法就行

extension UIView {
    func zhmfPositionInScreen() -> CGPoint {
        /// 先判断是否有父视图,如果没有父视图,直接返回视图的位置就行
        if let superView = self.superview {
            /**
            判断父视图是否是UIScrollView或者继承自UIScrollView
             
            先使用视图在屏幕上的位置使用视图的位置与父视图的位置X与Y分别相加
            
             如果父视图不是UIScrollView并且不继承自UIScrollView,则直接返回结果
            
             如果父视图是UIScrollView或者继承自UIScrollView

             还需要分别减去UIScrollView的scrollViewOffset.x和scrollViewOffset.y,然后返回结果
            */
            if let scrollView = superView as? UIScrollView {
                let position = CGPoint.init(x: self.frame.origin.x, y: self.frame.origin.y)
                let superPosition = superView.zhmfPositionInScreen()
                let scrollViewOffset = scrollView.contentOffset
                return CGPoint.init(x: superPosition.x + position.x - scrollViewOffset.x , y: superPosition.y + position.y - scrollViewOffset.y)
            } else {
                let superPosition = superView.zhmfPositionInScreen()
                let position = self.frame.origin
                return CGPoint.init(x: superPosition.x + position.x, y: superPosition.y + position.y)
            }
        } else {
            return self.frame.origin
        }
    }
}

获取视图在屏幕上位置的扩展方法已经写好了,只需要在使用的使用调一下就好了

button.zhmfPositionInScreen()

虽然代码量不大,但当时也花了一点时间想逻辑,没有去百度等搜索,能自己写的,还是自己花时间想吧,不然,脑子懒了,就真的只能是码农了。

新增:
突然发现,原来官方就给我们写好了转换的方法

guard let window = UIApplication.shared.keyWindow else {
    return
}        
topView = UIView.init(frame: .init(x: 100, y: 100, width: 100, height: 100))
let rect = topView.convert(topView.bounds, to: window)

这个方法没有测试过多个scrollView嵌套是否有效,喜欢折腾的同学可以自己去尝试下。

iOS开发,专注swift,如果想交流,随时欢迎,期待一起进步!!!

转载于:https://www.cnblogs.com/zhanbaocheng/p/7855937.html

相关文章:

  • Kali2.0通过xrdp实现windows远程链接Linux
  • Leetcode 117: Populating Next Right Pointers in Each Node II
  • js判断值对否为空
  • windows关闭aslr办法
  • YIT-CTF—社工类
  • jquery 怎么判断当前按钮是否是disabled 属性
  • 数据库的设计原则
  • HttpContext
  • js获取上传文件内容,ajax提交
  • “2017面向对象程序设计(Java)第十三周学习总结”存在问题的反馈及本周教学安排...
  • Python相关分析—一个金融场景的案例实操
  • hadoop入门
  • 如何将Win7做为NTP服务器
  • linux内存慢性扼杀
  • 命令行下显示mnist中图片的问题
  • 【技术性】Search知识
  • Android Volley源码解析
  • AWS实战 - 利用IAM对S3做访问控制
  • Docker: 容器互访的三种方式
  • express如何解决request entity too large问题
  • JAVA并发编程--1.基础概念
  • jquery ajax学习笔记
  • js继承的实现方法
  • nginx 负载服务器优化
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • Python 反序列化安全问题(二)
  • Spring-boot 启动时碰到的错误
  • Swoft 源码剖析 - 代码自动更新机制
  • TypeScript实现数据结构(一)栈,队列,链表
  • vue的全局变量和全局拦截请求器
  • 当SetTimeout遇到了字符串
  • 高性能JavaScript阅读简记(三)
  • 关于for循环的简单归纳
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 简单易用的leetcode开发测试工具(npm)
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 前端存储 - localStorage
  • 如何胜任知名企业的商业数据分析师?
  • 设计模式走一遍---观察者模式
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​业务双活的数据切换思路设计(下)
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • #、%和$符号在OGNL表达式中经常出现
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (九十四)函数和二维数组
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (转) ns2/nam与nam实现相关的文件
  • (转)四层和七层负载均衡的区别
  • (转载)Linux 多线程条件变量同步
  • (转载)OpenStack Hacker养成指南