iOS 10 iMessage 应用扩展:如何计算超高导航栏的高度

Posted

技术标签:

【中文标题】iOS 10 iMessage 应用扩展:如何计算超高导航栏的高度【英文标题】:iOS 10 iMessage app extension: how do i calculate the height of the extra tall navbar 【发布时间】:2016-10-19 13:43:50 【问题描述】:

我下载了 Xcode 8 测试版并尝试使用 iMessages 应用程序扩展 sdk,但遇到了看起来不标准的导航栏高度问题

当我过渡到应用程序的展开视图时,我的带有以下帧 CGRect(x: 0, y: 0, width: 100, height: 100) 的图像最终部分隐藏在导航栏后面。我希望它出现在导航栏下方。

我尝试了self.navigationController?.navigationBar.isTranslucent = false,但它不起作用,我想这是有道理的,因为它超出了我的应用程序的控制范围。

有人玩过这个吗?我想避免两件事。简单地猜测适当的高度并远离程序化解决方案。 感谢您的帮助

【问题讨论】:

是否可以在视图中添加约束?如果可能,请尝试从上边距添加 -86.0 的垂直空间约束。 我希望避免使用常量来解决这个问题。我更喜欢写一些东西,比如相对于导航栏高度以编程方式计算。 我已经用一个迷你演示更新了我的答案,说明如何让您使用处理自动调整大小的约束。 大声笑,您提供了我特别说过要避免的两种方法。但是感谢您的指点,我会添加一些约束并让您知道 如果您不添加约束,将很难自动处理不同设备的大小调整以及每种屏幕尺寸的紧凑和扩展模式。您的代码将很快变得庞大!最好不要对值进行硬编码,而是让 Apple 使用自动布局为您处理调整大小。你可以阅读更多关于自适应用户界面here! 【参考方案1】:

像这样对顶部布局指南进行约束可能会有所帮助:

view.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor).isActive = true

【讨论】:

@JosipB。是公认的答案......!但在目标 c 代码中不适用于我。我正在使用这个等效的[self.view.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor constant:8.0].active = YES;,但显然有些不同。 @jose920405 检查我在 ObjectiveC 中的答案【参考方案2】:

您可以从控制器的布局指南中获取高度:

self.topLayoutGuide.length

@Dilts 的演示之所以有效是因为标签的顶部是顶部布局指南的约束。如果它们是对超级视图的约束,那么它也会在栏后面。

【讨论】:

【参考方案3】:

如果你和我一样仍然觉得Auto Layout很难用,那么你可以使用viewDidLayoutSubviews的方法来自动调整视图大小。我有一个和你有同样问题的表格视图,所以我使用这个简单的方法来更改表格视图的顶部内容插图:

-(void)viewDidLayoutSubviews 
    [self.tableView setContentInset:UIEdgeInsetsMake(self.topLayoutGuide.length, 0, 0, 0)];

到目前为止,它在所有 iDevice 上都可以正常工作(纵向和横向)。

【讨论】:

【参考方案4】:

回答您的问题:“超高导航栏的高度是多少”:

它是 86 像素。

更新

关于隐藏用户界面的导航栏。我做了一个快速演示,没有任何问题。

我在视图顶部添加了几个标签(就在状态栏下方,y 点值为 20)。接下来我添加了 2 个约束:左侧标签的前导空间和顶部空间以及右侧标签的尾部空间和顶部空间。

这是我的结果,无论是紧凑模式还是扩展模式。所以只要确保你的组件低于 y-point-value 20 并且有一些限制,Apple 会为你调整视图大小!

【讨论】:

@stanley 我还尝试了UIImageView (启用了剪辑子视图和纵横比填充模式),并带有一些简单的约束,然后再次从 y-point-value 等于 20 开始并且它有效就像一个魅力! 你能提供项目吗?我尝试按照您的步骤操作,但它对我不起作用,谢谢 我被限制在顶部布局指南并且仍然被隐藏 如果您将顶部约束设置为顶部布局指南,它将从紧凑模式变为展开模式。但是,如果扩展以展开模式开始,它将不起作用。 @Dilts:这只适用于MessageViewController,它继承自MSMessagesAppViewController。但是当我们尝试对继承自 UIViewController 的 ViewController 执行相同操作时,这将不起作用。【参考方案5】:

如果将顶部布局指南设置为顶部约束,则它适用于 MSMessagesAppViewController。但它不适用于 UIViewControllers,因为布局指南不同。

除非您出于某种原因确实需要使用 UIViewController 类(例如:MessagesAppViewControllers 在包含 Obj C++ 代码时遇到问题),否则请坚持使用 MSMessagesAppViewController。

【讨论】:

【参考方案6】:

这是 Objective-C 中公认的答案

[view.topAnchor constraintEqualToAnchor:[self.topLayoutGuide bottomAnchor]].active = YES;

【讨论】:

您可以验证这是否有效?因为不这样做。你能帮我吗***.com/questions/41707159/… 您可以检查我的问题并确认我做错了,请【参考方案7】:

到目前为止,使用 Xcode 8.2,以上解决方案都不适合我。 @Dilts 答案仅适用于 MessageViewController,它继承自 MSMessagesAppViewController。但是当我们尝试对继承自 UIViewController 的 ViewController 执行相同操作时,这将不起作用。

我已经通过相对于视图而不是顶部布局指南绑定顶部约束来做到这一点。我将关于视图的顶部约束设置为零并将该约束绑定为 topLayout。

@IBOutlet weak var topLayout: NSLayoutConstraint!

然后在更改演示样式时以编程方式更改约束值。

override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) 
        // Called before the extension transitions to a new presentation style.

        if presentationStyle == .compact
            mediaViewController?.topLayout.constant = 0.0
        else

            mediaViewController?.topLayout.constant = 86.0
        

    

紧凑模式

扩展模式

【讨论】:

【参考方案8】:
    [self.view addConstraints: [NSArray arrayWithObjects:

                            [NSLayoutConstraint constraintWithItem:YourViewHere
                                                         attribute:NSLayoutAttributeTop
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self.topLayoutGuide
                                                         attribute:NSLayoutAttributeBottom
                                                        multiplier:1.0
                                                          constant:0.0],

                            [NSLayoutConstraint constraintWithItem:YourViewHere
                                                         attribute:NSLayoutAttributeBottom
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self.bottomLayoutGuide
                                                         attribute:NSLayoutAttributeTop
                                                        multiplier:1.0
                                                          constant:0.0],

                            [NSLayoutConstraint constraintWithItem:YourViewHere
                                                         attribute:NSLayoutAttributeLeft
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:[self view]
                                                         attribute:NSLayoutAttributeLeft
                                                        multiplier:1.0
                                                          constant:0.0],

                            [NSLayoutConstraint constraintWithItem:YourViewHere
                                                         attribute:NSLayoutAttributeRight
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:[self view]
                                                         attribute:NSLayoutAttributeRight
                                                        multiplier:1.0
                                                          constant:0.0], nil]];

【讨论】:

适用于限制到展开模式,对于折叠我只是将 self.view.frame 分配给我放置到折叠模式的视图的框架(减去我可能用于工具的一些偏移量bar),但我根据它所处的模式使用多个视图,不确定这些约束是否适用于折叠视图,因为我认为在折叠视图中顶部布局指南仍位于顶部

以上是关于iOS 10 iMessage 应用扩展:如何计算超高导航栏的高度的主要内容,如果未能解决你的问题,请参考以下文章

如何从 iOS 键盘扩展中检测到通过在 iMessage 中点击“发送”等操作清除了文本字段?

如何在 iOS 10 的 iMessage 应用程序中发送带有图像和标题的音频文件?

如何在没有 Xcode 10 错误的情况下将 pod FirebaseUI/Phone 添加到应用程序和 pod FirebaseUI/Storage 到 iMessage 扩展?

ios 11 imessage 扩展 message.url 无法打开 safari

iOS 10 iMessage 贴纸应用中 MSSticker Peels 的回调

IOS iMessage扩展截图检测