It’s important to optimize any UIView layoutSubviews method you create, as it can be frequently called, and has the potential for creating recursion (triggering a setNeedsLayout from layoutSubviews can create a loop that will grossly affect your apps performance). Layout subviews is called once per run loop on any view that has had setNeedsLayout or setNeedsDisplayWithRect: called on it. So in addition to any time you manually call these methods, it can be useful to know when the UI framework calls setNeedsLayout/setNeedsDisplay as this will trigger layoutSubviews.
For this purpose, I will define a few view relationships:
- View1 – UIView class, root view for examples
- View1.1 – UIScrollView class, subview of View1
- View1.1.1 – UIView class, subview of View1.1 (No autoresize mask)
- View1.1.2 – UIView class, another subview of View1.1 (Autoresize mask – flexible width)
I then ran the following tests. An X means the view was layed out
From this I surmise the following:
- init does not cause layoutSubviews to be called (duh)
- addSubview causes layoutSubviews to be called on the view being added, the view it’s being added to (target view), and all the subviews of the target view
- setFrame intelligently calls layoutSubviews on the view having it’s frame set only if the size parameter of the frame is different
- scrolling a UIScrollView causes layoutSubviews to be called on the scrollView, and it’s superview
- rotating a device only calls layoutSubview on the parent view (the responding viewControllers primary view)
- removeFromSuperview – layoutSubviews is called on superview only (not show in table)
Hopefully this is helpful information for you as well.
分享到:
相关推荐
How to subclass UIView and make friends with layoutSubviews How to build programmatic layouts without storyboards What is Auto Layout? What is a constraint? Who owns a constraint? How many ...
NSLog(@"%@ - layoutSubviews called", self); [self swizzled_layoutSubviews]; } ``` 在这个例子中,`layoutSubviews` 方法的原有实现被替换成 `swizzled_layoutSubviews`,并在调用原方法之前添加了日志输出...
当 UIView 设置为自动适配屏幕时,当用户旋转设备的时候,会调用 layoutSubviews 方法,我们只需重写这个方法,然后判断用户屏幕的方向。在调整每个空间的位置即可。 下面是一个简单的示例代码: ```objectivec -...
为了自定义气泡,我们需要创建一个新的`MAAnnotationView`子类,覆盖其`- (void)layoutSubviews`方法,以绘制我们自己的视图。 ```swift import AMapFoundationKit import AMapLocationKit import AMapMapKit ...
这可以通过重写`layoutSubviews()`方法实现: ```swift override func layoutSubviews() { super.layoutSubviews() // 在这里可以重新计算和设置文字的位置和大小,以适应新的视图尺寸 // ... setNeedsDisplay...
对于UITableView的cell,我们可以在`layoutSubviews`方法中设置contentView和backgroundView的layer.cornerRadius属性,确保在cell的尺寸改变时,圆角依然正确显示。同时,别忘了开启`masksToBounds`属性,这样子...
要给它添加渐变背景,开发者通常会自定义一个继承自`UITextView`的子类,然后覆写`layoutSubviews`方法。在这个方法中,可以创建并设置`CAGradientLayer`作为`UITextView`背景层。 以下是一段可能的代码实现: ```...
在这个子类中,我们可以重写`layoutSubviews`方法来计算和设置圆形路径的半径,确保它始终适应视图的大小。同时,我们还需要设置`CAShapeLayer`的`strokeStart`和`strokeEnd`属性来控制进度条的起始和结束位置,从而...
这里我们需要自定义一个`UITabBar`的子类,并覆盖其`layoutSubviews`方法: ```swift class CustomTabBar: UITabBar { var centralItemIndex: Int? // 中间按钮的索引 override func layoutSubviews() { ...
get { return _progress } set { willChangeValue(forKey: "progress") _progress = max(0, min(1, newValue)) didChangeValue(forKey: "progress") // 更新进度条形状... } } ``` 5. **交互与扩展**:为了...
此外,可能还需要覆盖`layoutSubviews()`方法,确保每次布局更新时更新渐变。 5. **添加动画**: 为了使按钮的渐变效果更具动态性,我们可以添加动画。Swift的`UIView.animate(withDuration:)`方法可用于在一定...
这可能需要重写`layoutSubviews()`方法来调整子视图的位置和大小。 ```swift override func layoutSubviews() { super.layoutSubviews() // 调整子视图布局... } ``` 4. **添加自定义行为**:如果需要监听用户...
你可以使用AutoLayout来实现这一点,或者在cell的`layoutSubviews`方法中手动设置子视图的约束。 ```swift class HorizontalTableViewCell: UITableViewCell { override func layoutSubviews() { super....
这可能包括在`layoutSubviews()`方法中更新按钮的位置和大小,以及在选中状态改变时更新按钮的视觉效果。 ```swift override func layoutSubviews() { super.layoutSubviews() // 更新布局 } ``` 以上就是`...
var showEmtpy: Bool { get } func configEmptyView() -> UIView? } ``` 接下来,我们创建一个扩展来处理UITableView的空数据视图。这里我们使用`DispatchQueue.once`确保`setEmtpyViewDelegate`方法只执行一次,...
在`init(frame:)`方法中设置初始的frame,并在`layoutSubviews()`方法中调整子视图的位置,确保当前图片始终居中显示。 ```swift override init(frame: CGRect) { super.init(frame: frame) setupCarousel() } ...
如果你需要更复杂的自定义,比如添加额外的UI元素或动画效果,可以创建一个自定义的`UITabBarController`子类,并重写`layoutSubviews`方法来绘制自定义的TabBar。 1. Objective-C: ```objc - (void)...
- 创建自定义的UIView子类作为section header,并在其中重写`layoutSubviews`方法,在这里设置阴影效果。 - 在`layoutSubviews`中设置layer的阴影属性,例如: ```swift override func layoutSubviews() { ...