gpt4 book ai didi

What is the correct way to call [super layoutSubviews]?(调用[Super LayoutSubview]的正确方式是什么?)

转载 作者:bug小助手 更新时间:2023-10-25 12:10:11 29 4
gpt4 key购买 nike



I just saw in the Facebook SDK for iOS that they call [super layoutSubviews]; at the end and not at the beginning of the layoutSubviews method.

我刚刚在iOS版的Facebook SDK中看到,他们在layoutSubviews方法的结尾而不是开头调用[Super layoutSubviews];。



As far as I know, we should always do it as the first line.
Can implementing it a different way cause any unexpected UI behavior?

据我所知,我们应该始终把它作为第一条线来做。以不同的方式实现它会导致任何意想不到的UI行为吗?



- (void)layoutSubviews
{
CGSize size = self.bounds.size;
CGSize longTitleSize = [self sizeThatFits:size title:[self _longLogInTitle]];
NSString *title = (longTitleSize.width <= size.width ?
[self _longLogInTitle] :
[self _shortLogInTitle]);
if (![title isEqualToString:[self titleForState:UIControlStateNormal]]) {
[self setTitle:title forState:UIControlStateNormal];
}

[super layoutSubviews];
}

更多回答

"As far as I know we should always do it as the first line" How do you "know" that?

据我所知,我们应该永远做的第一行,你是怎么知道的?

@matt, I believe this is the convention the iOS Developers Community uses as the super-class may have some default/general setup that may affect our custom layout not to be applied(if we do it at the end of the method). Similarly to calling super in constructors/initializers as the first line.

@Matt,我相信这是iOS开发者社区使用的约定,因为超类可能有一些默认/常规设置,这可能会影响我们的自定义布局不被应用(如果我们在方法结束时这样做)。类似于调用构造函数/初始值设定项中的Super作为第一行。

"the super-class may have some default/general setup that may affect our custom layout not to be applied(if we do it at the end of the method)." Yes, that's absolutely true. But that's not the same as "should always".

“超类可能有一些默认/常规设置,这可能会影响我们的自定义布局不被应用(如果我们在方法结束时应用)。”是的,这是绝对正确的。但这并不等同于“应该永远”。

优秀答案推荐

According to the UIView Class Reference,

根据UIView类引用,




The 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.




Thus, that the Facebook SDK example app calls [super layoutSubviews] at the end of their implementation could be an artifact of the app being initially built for an iOS version prior to iOS 5.1.

因此,Facebook SDK示例应用程序在其实现结束时调用[Super layoutSubview]可能是该应用程序最初为iOS 5.1之前的iOS版本构建的产物。



For more recent versions of iOS, you should call [super layoutSubviews] at the beginning of your implementation. Otherwise, the superclass will rearrange your subviews after you do the custom layout, effectively ignoring your implementation of layoutSubviews().

对于较新版本的iOS,您应该在开始实施时调用[Super layoutSubview]。否则,超类将在您完成定制布局后重新排列您的子视图,从而有效地忽略您的layoutSubviews()的实现。



look into the code, before [super layoutSubviews], it is not about the frame. so put it at the end may work well too.
I guess the coder must want to check the title and modify the title based on some rules, he thinks everytime the layoutSubviews being called is a right opportunity to do that, so he put the code here.

仔细看看代码,在[Super layoutSubview]之前,它不是关于框架的。因此,把它放在最后可能也会起到很好的作用。我猜程序员一定想要检查标题并根据一些规则修改标题,他认为每次调用layoutSubview都是这样做的正确机会,所以他将代码放在这里。



You always have to call [super layoutSubviews] last, if the intrinsic content size of a view will be changed. If you change the title of the button, the intrinsic content size of the UIButton will be changed, therefore the last call.

如果要更改视图的固有内容大小,则始终必须最后调用[Super layoutSubviews]。如果您更改按钮的标题,UIButton的固有内容大小也会更改,因此是最后一次调用。



The first call to [super layoutSubviews] is always required because iOS updates the layout based on the constraints.
However, the technical most correct way of implementing your sample should be:

第一次调用[super layoutSubviews]总是必需的,因为iOS会根据约束更新布局。但是,实现示例的最正确的技术方法应该是:



- (void)layoutSubviews
{
[super layoutSubviews];
CGSize size = self.bounds.size;
CGSize longTitleSize = [self sizeThatFits:size title:[self _longLogInTitle]];
NSString *title = (longTitleSize.width <= size.width ?
[self _longLogInTitle] :
[self _shortLogInTitle]);
if (![title isEqualToString:[self titleForState:UIControlStateNormal]]) {
[self setTitle:title forState:UIControlStateNormal];
}

[super layoutSubviews];
}


I recommend "Programming iOS" Matt Neuberg. It's my source of truth when I have problems like this described here.

我推荐《编程iOS》的马特·纽伯格。当我遇到这里描述的这样的问题时,这是我的真理之源。


Here is the quote that describes the rule:

以下是描述该规则的引语:



(...) you might override layoutSubviews when you’re using autolayout, in order to tweak the outcome. A typical structure is: first you call super, causing all the subviews to adopt their new frames; then you examine those frames; if you don’t like the outcome, you can change things; and finally you call super again, to get a new layout outcome.



(page 80)

(page(第80条)


更多回答

Just curious: is your claim about intrinsic content size backed up in the documentation anywhere?

只是好奇:你关于内在内容大小的声明是否在任何地方的文档中得到了支持?

Unfortunately not, but If you think about it: The intrinsic content size can only be updated with setNeedsLayout, which directly calls layoutSubviews. If you change the intrinsic content size (change button title) in layoutSubviews the container (Button) cannot apply these changes properly if [super layoutSubviews] will not be called afterwards.

不幸的是不能,但如果您想一想:固有的内容大小只能使用setNeedsLayout更新,它直接调用layoutSubview。如果更改layoutSubview中的固有内容大小(更改按钮标题),则如果之后不调用[Super layoutSubview],容器(Button)将无法正确应用这些更改。

@ndmeiri When running against iOS7, I've seen runtime errors if I only call [super layoutSubviews] first: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. {VIEW}'s implementation of -layoutSubviews needs to call super.'

@ndmeiri在iOS7上运行时,看到运行时错误,如果我只调用[Super layoutSubviews]首先:由于未捕获的异常‘NSInternalInconsistencyException’终止APP,原因:‘执行-layoutSubviews后仍需要自动布局。{view}’-layoutSubviews的S实现需要调用Super.

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com