Ios 调用[超级布局子视图]的正确方法是什么?

Ios 调用[超级布局子视图]的正确方法是什么?,ios,objective-c,facebook,sdk,Ios,Objective C,Facebook,Sdk,我刚刚在Facebook的iOS SDK中看到,他们称之为[super layoutSubviews]位于layoutSubviews方法的末尾,而不是开头 据我所知,我们应该始终把它作为第一行来做。 以不同的方式实现它会导致任何意外的UI行为吗 - (void)layoutSubviews { CGSize size = self.bounds.size; CGSize longTitleSize = [self sizeThatFits:size title:[self _longL

我刚刚在Facebook的iOS SDK中看到,他们称之为
[super layoutSubviews]
位于
layoutSubviews
方法的末尾,而不是开头

据我所知,我们应该始终把它作为第一行来做。 以不同的方式实现它会导致任何意外的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];
}
-(无效)布局子视图
{
CGSize size=self.bounds.size;
CGSize longTitleSize=[self sizeThatFits:size title:[self_longlogentitle];
NSString*title=(longTitleSize.width根据

此方法的默认实现在iOS 5.1及更早版本上不起任何作用。否则,默认实现将使用您设置的任何约束来确定任何子视图的大小和位置

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


对于较新版本的iOS,您应该在实现之初调用
[super layoutSubviews]
。否则,在您进行自定义布局后,超类将重新排列您的子视图,实际上会忽略您的
layoutSubviews()

实现。您始终必须调用
[super layoutSubviews]
last,如果视图的固有内容大小将被更改。如果更改按钮的标题,则
ui按钮的固有内容大小将被更改,因此最后一次调用

始终需要第一次调用
[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];
}
-(无效)布局子视图
{
[超级布局子视图];
CGSize size=self.bounds.size;
CGSize longTitleSize=[self sizeThatFits:size title:[self_longlogentitle];

NSString*title=(longTitleSize.width查看代码,在[super layoutSubviews]之前,它与框架无关。因此,将其放在末尾可能也很有效。
我猜编码人员一定想检查标题并根据一些规则修改标题,他认为每次调用LayoutSubview都是一个正确的机会,所以他将代码放在这里。

“据我所知,我们应该始终将其作为第一行”你怎么知道那?@matt,我相信这是iOS开发者社区使用的惯例,因为超级类可能有一些默认/常规设置,这可能会影响我们的自定义布局不被应用(如果我们在方法末尾这样做的话)。类似于在构造函数/初始值设定项中调用超级作为第一行。“超级类可能有一些默认/常规设置,可能会影响我们不应用的自定义布局(如果我们在方法末尾这样做)。”是的,这绝对正确。但这与“应该始终”不同“。只是好奇:您关于内在内容大小的声明是否在文档中的任何地方得到了备份?不幸的是,没有,但如果您仔细考虑一下:内在内容大小只能用setNeedsLayout更新,它直接调用layoutSubviews。如果您更改layoutSubviews中的内在内容大小(更改按钮标题),则容器(按钮)如果以后不调用[super LayoutSubView],则无法正确应用这些更改。@ndmeiri在运行iOS7时,如果只调用[super LayoutSubView],我会看到运行时错误第一:由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因是:“在执行-layoutSubviews之后仍然需要自动布局。{VIEW}的-layoutSubviews实现需要调用super。”