何时使用cell layoutsubviewss 方法

ios layout机制相关方法
——————-
——————–
- (void)setNeedsDisplay- (void)drawRect
layoutSubviews在以下情况下会被调用:
1、init初始化不会触发layoutSubviews
&&&但是是用initWithFrame&进行初始化时,当rect的值不为CGRectZero时,也会触发
2、addSubview会触发layoutSubviews
3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化
4、滚动一个UIScrollView会触发layoutSubviews
5、旋转Screen会触发父UIView上的layoutSubviews事件
6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件
在苹果的官方文档中强调:
&&&&&&You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.
&layoutSubviews, 当我们在某个类的内部调整子视图位置时,需要调用。
反过来的意思就是说:如果你想要在外部设置subviews的位置,就不要重写。
&刷新子对象布局
-layoutSubviews方法:这个方法,默认没有做任何事情,需要子类进行重写
-setNeedsLayout方法: 标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,但layoutSubviews一定会被调用
-layoutIfNeeded方法:如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)
如果要立即刷新,要先调用[view&setNeedsLayout],把标记设为需要布局,然后马上调用[view&layoutIfNeeded],实现布局
在视图第一次显示之前,标记总是“需要刷新”的,可以直接调用[view layoutIfNeeded]
-drawRect:(CGRect)rect方法:重写此方法,执行重绘任务
-setNeedsDisplay方法:标记为需要重绘,异步调用drawRect
-setNeedsDisplayInRect:(CGRect)invalidRect方法:标记为需要局部重绘
sizeToFit会自动调用sizeThatFits方法;
sizeToFit不应该在子类中被重写,应该重写sizeThatFits
sizeThatFits传入的参数是receiver当前的size,返回一个适合的size
sizeToFit可以被手动直接调用
sizeToFit和sizeThatFits方法都没有递归,对subviews也不负责,只负责自己
———————————-
layoutSubviews对subviews重新布局
layoutSubviews方法调用先于drawRect
setNeedsLayout在receiver标上一个需要被重新布局的标记,在系统runloop的下一个周期自动调用layoutSubviews
layoutIfNeeded方法如其名,UIKit会判断该receiver是否需要layout.根据Apple官方文档,layoutIfNeeded方法应该是这样的
&layoutIfNeeded遍历的不是superview链,应该是subviews链
drawRect是对receiver的重绘,能获得context
setNeedDisplay在receiver标上一个需要被重新绘图的标记,在下一个draw周期自动重绘,iphone device的刷新频率是60hz,也就是1/60秒后重绘
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:36213次
排名:千里之外
转载:70篇
(1)(1)(3)(5)(4)(1)(1)(2)(1)(1)(4)(1)(1)(5)(7)(9)(15)(12)(3)(1)2551人阅读
cocoa SDK(139)
首先两个方法都是异步执行。layoutSubviews方便数据计算,drawRect方便视图重绘。
layoutSubviews在以下情况下会被调用:
1、init初始化不会触发layoutSubviews。
2、addSubview会触发layoutSubviews。
3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。
4、滚动一个UIScrollView会触发layoutSubviews。
5、旋转Screen会触发父UIView上的layoutSubviews事件。
6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。
7、直接调用setLayoutSubviews。
drawRect在以下情况下会被调用:
1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect 掉用是在Controller-&loadView,&Controller-&viewDidLoad&两方法之后掉用的.所以不用担心在 控制器中,这些View的drawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View&draw的时候需要用到某些变量
值).
2、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。
3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。
4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。
以上1,2推荐;而3,4不提倡
drawRect方法使用注意点:
1、 若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个invalidate 的ref并且不能用于画图。drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay&或 者&setNeedsDisplayInRect,让系统自动调该方法。
2、若使用calayer绘图,只能在drawInContext:&中(类似于drawRect)绘制,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法
3、若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来调用setNeedsDisplay实时刷新屏幕
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:576468次
积分:6065
积分:6065
排名:第2752名
原创:57篇
转载:220篇
评论:55条
(3)(1)(1)(1)(1)(6)(3)(1)(9)(4)(12)(8)(26)(4)(11)(21)(21)(30)(91)(1)(2)(1)(5)(14)使用过 Auto Layout 的人肯定都遇到过获取不到真实 frame 的情况,而大部分人经过简单搜索都能得到一个满意的:在想获取真实 frame 之前调用一下 self.view.layoutIfNeeded(),这是一个能用但是并不好的方法:进行了额外的毫不需要的 frame 计算。
我们从 View Controller 的生命周期来分析这个问题:
viewDidLoadviewWillAppearviewWillLayoutSubviewsviewDidLayoutSubviewsviewDidAppearviewWillDisappearviewDidDisappear
Auto Layout 的布局是从外到内的,即从屏幕尺寸开始布局,一直布局到最里面的细节,我们的目光自然地落在了 viewDidLayoutSubviews 和 viewDidAppear 上了:
viewDidLayoutSubviews 时当前视图已经把子元素布局完毕,frame 已经形成
viewDidAppear 时,渲染系统把当前视图加入父视图中,显示在屏幕上
所以,解决方案其实已经水落石出了:
避免调用 layoutSubviews,在 viewDidLayoutSubviews 和 viewDidAppear 中进行 frame 的获取
如果你需要尽早地做一些大动作,推荐在 viewDidLayoutSubviews,此时用户还没有看到 UI,用法可以更灵活
注意 viewDidLayoutSubviews 可能会被多次调用,所以添加元素之类的操作尽量避免在这里做
viewDidAppear 中可以干一切你想干的事情,但是一些需要用户看到的东西例如动画只能在这里做
更推荐把需要做的事情尽量全部放到 viewDidAppear 中来做,让用户尽早地看到界面,这是人机交互的基本原则
回到标题中的问题:什么时候才能获得正确的 frame? 在 viewDidLayoutSubviews 和 viewDidAppear 中。
本文永久更新链接地址:10867人阅读
今天在写程序时候遇见layoutSubviews触发时候引起的问题。特来总结一下什么时候会触发layoutSubviews:
layoutSubviews在以下情况下会被调用:&
1、init初始化不会触发layoutSubviews&
2、addSubview会触发layoutSubviews&
3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化&
4、滚动一个UIScrollView会触发layoutSubviews&
5、旋转Screen会触发父UIView上的layoutSubviews事件&
6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:412814次
积分:3711
积分:3711
排名:第5995名
原创:32篇
转载:66篇
评论:44条
(1)(4)(1)(1)(3)(2)(4)(1)(1)(1)(5)(3)(1)(3)(2)(3)(5)(4)(3)(1)(8)(7)(7)(1)(2)(5)(1)(1)(1)(4)(5)(7)layoutSubviewsLays out subviews.- (void)layoutSubviewsDiscussionThe default implementation of this method does nothing on iOS 5.1 and earlier. Otherwise, the default implementation uses any constraints you have set to determine the size and position of any subviews.Subclasses can override this method as needed to perform more precise layout of their subviews. You should override this method only if the autoresizing and constraint-based behaviors of the subviews do not offer the behavior you want. You can use your implementation to set the frame rectangles of your subviews directly.You should not call this method directly. If you want to force a layout update, call the&setNeedsLayout&method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the&layoutIfNeeded&method.AvailabilityAvailable in iOS 2.0 and later.setNeedsLayoutInvalidates the current layout of the receiver and triggers a layout update during the next update cycle.- (void)setNeedsLayoutDiscussionCall this method on your application&s main thread when you want to adjust the layout of a view&s subviews. This method makes a note of the request and returns immediately. Because this method does not force an immediate update, but instead waits for the next update cycle, you can use it to invalidate the layout of multiple views before any of those views are updated. This behavior allows you to consolidate(合并) all of your layout updates to one update cycle, which is usually better for performance.AvailabilityAvailable in iOS 2.0 and later.&layoutIfNeededLays out the subviews immediately.- (void)layoutIfNeededDiscussionUse this method to force the layout of subviews before drawing. Starting with the receiver, this method traverses upward(向上遍历) through the view hierarchy as long as(只要) superviews require layout. Then it lays out the entire tree beneath(在下方) that ancestor(祖先). Therefore, calling this method can potentially(可能) force the layout of your entire view hierarchy. The&UIView&implementation of this calls the equivalent&CALayer&method and so has the same behavior as&CALayer.AvailabilityAvailable in iOS 2.0 and later. 1 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 2 { 3
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) 4
self.accessoryType = UITableViewCellAccessoryDetailDisclosureB 6
// cell's title label 8
self.textLabel.backgroundColor = self.backgroundC 9
self.textLabel.opaque = NO;10
self.textLabel.textColor = [UIColor blackColor];11
self.textLabel.highlightedTextColor = [UIColor whiteColor];12
self.textLabel.font = [UIFont boldSystemFontOfSize:18.0];13
// cell's check button15
checkButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];16
checkButton.frame = CGRectZ17
checkButton.contentVerticalAlignment = UIControlContentVerticalAlignmentC18
checkButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentC19
[checkButton addTarget:self action:@selector(checkAction:) forControlEvents:UIControlEventTouchDown];20
checkButton.backgroundColor = self.backgroundC21
[self.contentView addSubview:checkButton];22
} - (void)layoutSubviews27 {28
[super layoutSubviews];29
CGRect contentRect = [self.contentView bounds];31
CGRect frame = CGRectMake(contentRect.origin.x + 40.0, 8.0, contentRect.size.width, 30.0);33
self.textLabel.frame =34
// layout the check button image36
UIImage *checkedImage = [UIImage imageNamed:@"checked.png"];37
frame = CGRectMake(contentRect.origin.x + 10.0, 12.0, checkedImage.size.width, checkedImage.size.height);38
checkButton.frame =39
UIImage *image = (self.checked) ? checkedImage: [UIImage imageNamed:@"unchecked.png"];41
UIImage *newImage = [image stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0];42
[checkButton setBackgroundImage:newImage forState:UIControlStateNormal];43 }&setNeedsDisplayMarks the receiver&s entire bounds rectangle as needing to be redrawn.- (void)setNeedsDisplayDiscussionYou can use this method or the&setNeedsDisplayInRect:&to notify the system that your view&s contents need to be redrawn. This method makes a note of the request and returns immediately. The view is not actually redrawn until the next drawing cycle, at which point all invalidated views are updated.Note:&If your view is backed by a&CAEAGLLayer&object, this method has no effect. It is intended for use only with views that use native drawing technologies (such as UIKit and Core Graphics) to render their content.&You should use this method to request that a view be redrawn only when the content or appearance of the view change. If you simply change the geometry of the view, the view is typically not redrawn. Instead, its existing content is adjusted based on the value in the view&s&contentMode&property. Redisplaying the existing content improves performance by avoiding the need to redraw content that has not changed.AvailabilityAvailable in iOS 2.0 and later.See Also&&drawRect:&&setNeedsDisplayInRect:&&@property&contentMode1 - (void)init2 {3
needleLayer = [CALayer layer];4
needleLayer.bounds = self.5
needleLayer.position = CGPointMake(self.bounds.size.width / 2.0, self.bounds.size.height / 2.0);6
needleLayer.needsDisplayOnBoundsChange = YES;
[self.layer addSublayer:needleLayer];
[needleLayer setNeedsDisplay];9 }&
、 、 、 、 、}

我要回帖

更多关于 layoutsubviews 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信