首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

layoutSubviews不是应该每帧只被调用一次吗?

layoutSubviews是UIView类中的一个方法,用于对子视图进行布局。它的调用时机是在以下情况下:

  1. 当视图的frame发生变化时,比如视图的大小或位置发生改变。
  2. 当视图的bounds发生变化时,比如视图的大小发生改变。
  3. 当视图的transform发生变化时,比如视图进行了旋转、缩放等操作。
  4. 当视图的子视图发生变化时,比如添加或移除了子视图。

因此,layoutSubviews方法的调用并不是每帧都会被调用一次,而是在上述情况下进行布局更新。这是因为每帧都调用layoutSubviews会导致性能开销过大,影响应用的流畅度。

在布局过程中,可以通过重写layoutSubviews方法来自定义子视图的布局逻辑。可以根据具体需求,设置子视图的位置、大小、间距等属性,以实现灵活的布局效果。

对于layoutSubviews方法的优势和应用场景,可以总结如下:

优势:

  1. 灵活性:通过重写layoutSubviews方法,可以自定义子视图的布局逻辑,实现各种复杂的布局效果。
  2. 响应式布局:当视图的大小或位置发生变化时,layoutSubviews方法会被自动调用,确保布局的实时更新。

应用场景:

  1. 自定义视图布局:当需要实现特定的视图布局效果时,可以通过重写layoutSubviews方法来实现。
  2. 响应式布局:当需要根据视图的大小或位置动态调整子视图的布局时,可以利用layoutSubviews方法来实现。

腾讯云相关产品和产品介绍链接地址: 腾讯云提供了丰富的云计算产品和服务,包括云服务器、云数据库、云存储等。具体推荐的产品和介绍链接如下:

  1. 云服务器(CVM):提供弹性计算能力,支持多种操作系统和应用场景。详情请参考:https://cloud.tencent.com/product/cvm
  2. 云数据库MySQL版(CDB):提供稳定可靠的云数据库服务,支持高可用、备份恢复等功能。详情请参考:https://cloud.tencent.com/product/cdb_mysql
  3. 云存储(COS):提供安全可靠的对象存储服务,适用于图片、音视频、文档等各种类型的数据存储。详情请参考:https://cloud.tencent.com/product/cos

请注意,以上推荐的腾讯云产品仅供参考,具体选择应根据实际需求进行。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

layoutSubviews 详解

,不立即刷新,但layoutSubviews一定会被调用 -layoutIfNeeded方法:如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews...) 如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局 在视图第一次显示之前,标记总是“需要刷新...sizeToFit不应该在子类中被重写,应该重写sizeThatFits sizeThatFits传入的参数是receiver当前的size,返回一个适合的size sizeToFit可以手动直接调用...sizeToFit和sizeThatFits方法都没有递归,对subviews也不负责,负责自己 ———————————- layoutSubviews对subviews重新布局 layoutSubviews...方法如其名,UIKit会判断该receiver是否需要layout.根据Apple官方文档,layoutIfNeeded方法应该是这样的 layoutIfNeeded遍历的不是superview链,

47130

layoutSubviews总结

刷新子对象布局 -layoutSubviews方法:这种方法,默认没有做不论什么事情,须要子类进行重写 -setNeedsLayout方法: 标记为须要又一次布局,异步调用layoutIfNeeded...) 假设要立即刷新,要先调用[view setNeedsLayout],把标记设为须要布局,然后立即调用[view layoutIfNeeded],实现布局 在视图第一次显示之前,标记总是“须要刷新...; sizeToFit不应该在子类中被重写,应该重写sizeThatFits sizeThatFits传入的參数是receiver当前的size,返回一个适合的size sizeToFit能够手动直接调用...方法调用先于drawRect setNeedsLayout在receiver标上一个须要被又一次布局的标记,在系统runloop的下一个周期自己主动调用layoutSubviews layoutIfNeeded...方法如其名,UIKit会推断该receiver是否须要layout.依据Apple官方文档,layoutIfNeeded方法应该是这种 layoutIfNeeded遍历的不是superview链,应该

22920
  • setNeedsLayout和layoutIfNeeded看我就懂!

    针对网上大部分资料讲得不够清晰,我决定用Demo来讲解 一、layoutSubviews 不能直接调用这个方法。...当这样的约束更新时,它会自动执行相当于setNeedsLayout的操作,因此在下一个更新周期内不需要更新视图。我们可以没有更多的代码,你会看到更新,但它不会有动画效果。...** 因此,由于我们的代码已经标记该视图需要通过setNeedsLayout进行布局更新,所以是在更新周期中立即启动视图更新,而不是从更新周期开始约束更改和移动的动画。...刷新布局,不立即刷新,但layoutSubviews一定会被调用 -layoutIfNeeded方法:如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews...) 如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局 在视图第一次显示之前,标记总是“需要刷新”的

    2.7K90

    屏幕成像原理以及FPS优化Tips

    随后 GPU 会把渲染结果提交到缓冲区去,等待下一次 VSync 信号到来时显示到屏幕上。...由于垂直同步的机制,如果在一个 VSync 时间内,CPU 或者 GPU 没有完成内容提交,则那一就会被丢弃,等待下一次机会再显示,而这时显示屏会保留之前的内容不变。这就是界面卡顿的原因。...尽量提前计算好布局,一次性设置给UIView,避免多次设置。...如果确定子视图大小和位置是固定的,那么避免在cell的layoutSubViews中设置子视图的位置和大小。因为tableView滚动时候会调用cell的layoutSubView方法。...当layer调用dealloc、setNeedsDisplay、就会递增这个变量,异步绘制过程中会多次检查这个变量来判断此次绘制任务是否应该取消。

    9.6K73

    iOS开发-视图渲染与性能优化

    提交流程(以动画为例) 第2步为prepare to commit animation (layoutSubviews,drawRect:); ?...1、布局(Layout) 调用layoutSubviews方法; 调用addSubview:方法; 会造成CPU和I/O瓶颈; 2、显示(Display) 通过drawRect绘制视图; 绘制...使用UIBlurEffect,应该是尽可能小的view,因为性能消耗巨大。 ? 4、渲染等待 由于的顶点和像素处理相对独立,iOS会将CPU处理,顶点处理,像素处理安排在相邻的三中。...更新内容时,会启用离屏渲染,所以更新代价较大,只能用于静态内容;而且如果光栅化的元素100ms没有使用将被移除,故而不常用元素的光栅化并不会优化显示。...使用真机来调试,因为模拟器使用的CALayer是OSX的CALayer,不是iOS的CALayer。如果用模拟器调试,会发现所有的视图都是黄色。

    1.7K70

    UIViewController生命周期

    一、视图控制器 UIViewController采用懒加载的方式,也就是说第一次访问到view属性时才会加载或创建它。...三、UIView生命周期其他点 layoutSubviews调用的时机: addSubview会触发layoutSubviews,比如viewA add viewB,第一次添加A和B的layoutSubviews...都会被调用,而第二次(viewA已经有了viewB)调用viewB的 view的Frame变化会触发layoutSubviews 滚动一个UIScrollView会触发layoutSubviews 旋转...生命周期: application didFinishLaunchingWithOptions:当应用程序启动时执行,应用程序启动入口,在应用程序启动时执行一次。...applicationWillEnterForeground:在应用程序将要进入前台时(激活),要执行的委托调用,刚好与applicationWillResignActive 方法相对应。

    1.9K10

    iOS项目——自定义UITabBar与布局

    主要缺点就是需要先申请一个位置和控制器来占位比较浪费,而且这种也适用于各控件的大小是均匀的情况,当我们需求中每个TabBarItem的规格和尺寸不一样时,我们就无法使用这种方案实现。   ...至于为什么要在 viewWillAppear: 中添加【发布】按钮而不是在 viewDidLoad 中添加?...* 当viewWillAppear:方法调用的时候, tabBar内部已经添加了5个UITabBarButton * 就可以实现一个效果 : [发布按钮]盖在其他UITabBarButton上面...同样的,也有几点需要注意的: 【发布】按钮的初始化还是和上面一样,应该采用单例模式进行初始化,具体就不展开; 重写  方法时,应该调用其父类的此方法 [super layoutSubviews]; ,...调用父类布局方法的语句不能放在后面,更不能省略,因为此方法除了对TabBarItem进行布局之外还有很多其他的配置; layoutSubviews 通过  来获取当前的子控件,我们可以先进行打印了解当前子控件的类型和数量

    3K90

    OpenGL ES学习阶段性总结

    ,并切换前后缓存; OpenGL ES坐标是以浮点数来存储,即使是其他数据类型的顶点数据也会被转化成浮点型; framebuffer object 通常也称之为 FBO,它相当于 buffer(...在使用完缓存后,可以调用glBindBuffer把array绑定的对象重置为0,防止其他地方误用;(注意,纹理对象需要在使用完后,再glBindTexture绑定为0) CAEAGLLayer会与OpenGL...在自定义UIView实现渲染时,需要在调整视图大小的回调中(layoutSubviews),调用-renderbufferStorage:fromDrawable: 方法来调整视图的尺寸,从而匹配层的新尺寸...理想状态下,缓存生成后就不发生变化; 生成、初始化和删除缓存需要耗费时间来同步GPU和CPU,大多数情况下是CPU等待GPU,因为GPU在删除缓存之前必须等待该缓存相关的指令全部执行完毕; 故而一个程序在都进行生成和删除缓存会有严重的性能消耗...应该是每行宽度 * 高度值,每行宽度可能会有填充的空字节。

    2.1K80

    iOS 页面渲染 - 流程

    CRT 的电子枪从上到下逐行扫描,扫描完成后显示器就呈现一画面。然后电子枪回到初始位置进行下一次扫描。为了同步显示器的显示过程和系统的视频控制器,显示器会用硬件时钟产生一系列的定时信号。...虽然V-Sync解决了画面撕裂问题,但是如果在一个 VSync 时间周期内,CPU 或者 GPU 没有完成内容提交,则那一就会被丢弃,等待下一次机会再显示,而这时显示屏会保留之前的内容不变。...Layout 这个阶段主要处理视图的构建和布局,具体步骤包括: 调用重载的 layoutSubviews 方法 创建视图,并通过 addSubview 方法添加子视图 计算视图布局,即所有的 Layout...我们也可以不依赖 Render Server而实现动画,那我们就可以使用 Facebook 的 pop[2],其核心原理是利用CADisplayLink来完成的提交渲染来实现动画。...产生 VSync 信号的进程, 16.7ms 进行一次到这个 port 的 mach msg 发送工作,从而不断的激活本 App 的 Runloop ,触发一个 item,完成本 App 对 VSync

    1.9K20

    iOS开发-OpenGLES进阶教程4

    GLKit进阶 OpenGLES进阶教程1-Tutorial05-地球月亮 OpenGLES进阶教程2-Tutorial06-光线 OpenGLES进阶教程3-Tutorial07-粒子效果 这一次的内容是缓存...因为需要拿到第一次渲染的结果-纹理Texture0,就想尝试新建上下文mExtraContext来渲染纹理,然后用原来的上下文mBaseContext来进行接收纹理和渲染。...在渲染纹理Texture0的时候使用不同的视口大小,但是没有调用glviewport()。...渲染到一个纹理后,再被显示到屏幕上。 ? 思考 答案:CAEGLayer OpenGL ES会有连接到层,与层分享数据的缓存,至少包括一个像素颜色渲染缓存。...可以在layoutSubviews方法里面删除现存的深度缓存,并创建一个新的与像素颜色渲染缓存的新尺寸相匹配的深度缓存。 ? 总结 这个demo不难,但是很考验对缓存的理解。

    86740

    Kotlin|这些隐藏的内存陷阱,你应该熟记于心

    Jvm在执行方法时,执行一个方法会产生一个栈,随后将其保存到我们当前线程所对应的栈里,方法执行完毕时再将此方法出栈, 所以内联后就相当于省了一个栈调用。...如果上述描述中,你记住了后半句,降低栈 ,那么此时你可能已经陷入了一个使用陷阱?...不是说内联可以提高性能,那么不应该任何方法都应该加 inline 提高性能?(就是这么倔强) 上面我们提到了,内联是会将代码移动到调用处,降低 一层栈,但这个性能提升真的大?...假设我们某个方法里代码只有两行(我想不会有人会某个方法只有一行吧),这个方法又被好几处调用,内联是提高了调用性能,毕竟节省了一次,再加上方法行数少(暂时抛弃虚拟机优化这个底层条件)。...总结如下: 因为内联函数会将方法函数移动到调用处,会增加调用处的代码量,所以对于较长的方法应该避免使用; 内联函数应该用于使用了 高阶函数(lambda) 的方法,而不是普通方法。

    81030

    requestAnimationFrame,终结定时器动画时代!

    当然可行,完美?也还算完美,当突然发现新大陆以后,定时器便彻底终结了,就比如,你用了苹果的Retina屏幕以后,发现再也回不去了是一个道理,你说1080p的屏幕完美?...我们知道定时器的执行时间并不是确定的。这是由于js是个单线程的语言,他必须使用异步,来解决一些需要延时执行这个问题,那么为什么说定时器的执行时间不是确定的呢?...JS调用栈采用的是后进先出的规则,当函数执行的时候,会被添加到栈的顶部,当执行栈执行完成后,就会从栈顶移出,直到栈内清空。...(后经过大佬更正,定时器丢帧的原因仅仅是没有浏览器的策略干涉,并不是会被同步任务阻塞) //这段代码可以证实 requestAnimationFrame(() => console.log(...1、requestAnimationFrame 会把中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60

    1.4K20

    Matrix TraceCanary -- 初恋·卡顿

    在使用 App 时,有些人遇上这弹框应该会是一本正经,而有些人看到了估计一脸懵逼(黑人❓)。当然,这里我们要讨论的不是什么初恋,而是对大多数开发者来说,戏虐你千百遍,回头对它如初恋的卡顿。...又或者低 FPS 真的就是卡顿?...假设准备时间约 32ms,每次掉一,那么 1 秒内实际刷新 30 ,即平均帧率只有 30FPS,但这时往往不会觉得是卡顿。...反而如果出现某次严重掉(>300ms),那么这一次的变化,通常很容易感知到。所以界面的掉程度,往往可以更直观的反映出卡顿。...通过遍历采集的 buffer ,相邻 i 与 o 为一次完整函数执行,计算出一个调用树及每个函数执行耗时,并对一级中的一些相同执行函数做聚合,最后通过一个简单策略,分析出主要耗时的那一级函数,作为代表卡顿堆栈的

    4.2K41

    App的生命周期

    awakeFromNib 当awakeFromNib方法调用时,所有视图的outlet和action已经连接,但还没有确定,这个方法可以算作适合视图控制器的实例化配合一起使用的,因为有些需要根据用户喜好来进行设置的内容...loadView方法在UIViewController对象的view访问且为空的时候调用。这是它与awakeFromNib方法的一个区别。...因此loadView方法在视图控制器的生命周期内可能调用多次。...loadView方法不应该直接调用,而是由系统调用,它会加载或创建一个view并把它赋值给UIViewController的view属性。...viewDidAppear 在view添加到视图层级中以及多视图,上下级视图切换时调用这个方法,在这里可以对正在显示的视图做进一步的设置。

    1.3K10

    PYTHON知识点学习-函数(中)

    --->不是同一组变量!只不过名字恰好相同!! --->函数内部的变量名,只能在函数内部生效,出了函数,就无效了!!...在上述语句内部定义的变量,可以在外面访问!!.... 2.2debug step summary(调试步骤总结): 1.先在开始调试处加间断点. 2.右击鼠标开始调试,程序会真的快速运行到调试点暂停. 3.然后点击单步执行的按钮就可以通过一次次点击查看一步的运行过程..." 调用栈里面描述了当前这个代码的函数之间调用关系是啥~ ~ 一层这个调用关系就称为"函数的栈",每个函数的局部变量就在这个栈中体现的~ 5.2栈与局部变量的关系 从上面可以看出局部变量和栈就像是同生共死的好朋友一样...~ 一层栈,你选中了之后,都能看到里面的局部变量 每个函数的局部变量就保存在对应得栈中~ ~ 调用函数,则生成对应的栈.

    14110
    领券