今天iPad的扩展高度远大于指定

Jor*_*n H 51 ios autolayout ios8 ios-app-extension ios8-today-widget

My Today扩展需要基于窗口小部件显示的内容具有动态高度.我能够通过在最底部元素上添加约束来实现这一点:底部布局指南的顶部小于或等于最底部元素的底部,常量为0,优先级为999,乘数为1.

这与iPhone上的预期完全一样 - 小部件高度适合所有内容,并且在显示下一个小部件之前应用默认的底部边距.

但是在iPad上似乎将我的小部件的高度设置为等于最大高度通知中心将允许小部件 - 我的小部件下方有很多空间,它几乎全屏.

如何删除多余的空间?

我确切地知道问题是什么,但我不确定如何解决它 - 请参阅"问题"部分.首先让我解释一下设置:

设置:
我在故事板中设置了此扩展的视图,没有任何编程方式.视图由垂直堆叠的5个元素组成,其他一些元素水平堆叠.这些是从上到下的垂直线的自动布局约束 - 其中未声明的优先级为1000,乘数1:

UILabel: height = 35, top space to top layout guide with constant of 10
UIButton: equal height and width to a different button (whose aspect ratio is 1:1, there is no fixed width/height), top space to label 10
UIButton: equal height and width to same button, top space to above button 8
UIButton: equal height and width to same button, top space to above button 8
UIButton: equal height and width to same button, top space to above button 8, bottom space to bottom layout guide <= 0 with priority 999
Run Code Online (Sandbox Code Playgroud)

必要的行为:

  • 我需要一个位于单个全宽标签下方的4x4按钮网格
  • 每个按钮应该是完全相同的宽度和高度 - 所有完美的正方形
  • 最后一排按钮下面没有多余的空间

结果:
在此输入图像描述

预期成果:
在此输入图像描述

问题:
所有按钮上的宽高比限制最终间接地对窗口小部件视图在发送时的高度施加"隐式"宽高比约束systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:,其中它以所需优先级传递必要宽度(724)以进行布局在拟合水平优先级高度为0(以压缩视图).这导致iPad上的高小部件视图开始时视图更宽.但是没有可以删除的实际宽高比约束.本质上,因为我已经将宽高比约束应用于所有按钮,所以今天扩展的高度取决于其宽度(考虑所有约束,宽高比等).因此,扩展的高度在广泛的区域中是笨拙的,在iPad等宽的设备上表现出来.需要重新考虑对按钮的约束,或以某种方式调整.

示例项目:
一个演示问题示例项目可从CloudApp这样你就可以下载并使用它.

我试过的:
我尝试通过覆盖widgetMarginInsetsForProposedMarginInsets并返回0底部来删除默认的边距插入.这确实删除了默认填充,因此稍微降低了高度,但是在它下面仍然有很多额外的空间.

UILabel有一个约束:标签的前导等于超级视图的前导 - 常数0,优先级1000,乘数1.如果我只是将其更改为超视图的前导边距,额外的底部间距会神奇地消失.我想知道是不是因为元素变得太大,所以增加左边距会减少它们的大小,但是我试着将它设置为常规前导并增加常量并且没有解决问题.但这只能解决iPad中的问题.它甚至没有完全解决它,每次你拉下通知中心它从大高度开始然后缩小到适当的大小.在景观中它永远不会收缩到适当的大小.

尝试的解决方案:

  • @Lefteris提出了硬编码的大小,在这种情况下这不会起作用,因为高度是动态的,并且小部件可用于许多屏幕尺寸/方向.
  • @Yuyutsu试图解决它,但遗憾的是它不符合要求并展示了相互矛盾的约束和修改后的布局.

Lef*_*ris -1

我必须在viewDidLoad委托方法上对小部件的值进行硬编码才能解决此问题:

import UIKit
import NotificationCenter

class TodayViewController: UIViewController, NCWidgetProviding {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.preferredContentSize = CGSize(width: 0, height: 320)
    }

}
Run Code Online (Sandbox Code Playgroud)