问题
别人建的Cell需要多选删除时出现UITableViewCellEditControl
被遮挡的情况,如下图:
原因
经过排查发现时Cell布局代码有问题:
原来的代码在 -initWithStyle:reuseIdentifier:
方法中添加 subView
,在 layoutSubviews
中对子控件进行布局, 并在设置 model
的时候调用 [self layoutIfNeeded];
并触发 layoutSubviews
。
原代码没有调用[super layoutSubviews];
解决
经过把 layoutSubviews
中对子控件的布局移动到 layoutSubviews
方法后,问题解决。
layoutSubviews
的使用和调用时机
参考文档:
如果子控件的布局约束无法满足需求,需要对子控件更改布局时可以重写layoutSubviews
,可以直接设置子控件的 frame 。
不能直接调用layoutSubviews
。 如果要强制进行布局更新,请在下次绘图更新之前调用 setNeedsLayout
方法。 如果要立即更新视图的布局,请调用layoutIfNeeded
方法。
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 thesetNeedsLayoutmethod 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.
调用时机
1、init
初始化不会触发layoutSubviews
;
2、addSubview
会触发layoutSubviews
,如果添加的子控件没有 Frame ,不会调用;
3、设置 view 的 Frame 会触发layoutSubviews
,当然前提是frame的值设置前后发生了变化且该 View 已经被添加到父控件;
4、滚动一个 UIScrollView
会触发 layoutSubviews
,因滚动 UIScrollView
,其子控件肯定对应会刷新,也就肯定会被调用;
5、旋转 Screen 会触发控制器对应 UIView
上的 layoutSubviews
事件;
总结:改变子控件就会调用父类的方法;
注:在一个方法内连续调(主动调用或者系统隐式调用),都只会调一次layoutSubviews;
参考文档:layoutSubviews 调用时机