iOS 10 iMessage应用程序扩展:如何计算额外高的导航栏的高度?

21

我下载了 Xcode 8 beta 并尝试使用 iMessages 应用扩展 SDK 进行实验,但遇到了一个问题,即它们看似非标准的导航栏高度。

当我切换到应用程序的扩展视图时,我的图像带有以下框架 CGRect(x: 0, y: 0, width: 100, height: 100),会部分隐藏在导航栏后面。我希望它出现在导航栏下方。

我尝试使用 self.navigationController?.navigationBar.isTranslucent = false,但没有起作用。我猜这是因为它超出了我的应用程序控制范围而无法解决。

有人尝试过这个吗?我想避免两件事情:只是猜测适当的高度和远离编程式的解决方案。 compact expanded 感谢帮助。


哈哈,你提供了我明确要避免的两种方法。但还是谢谢你的建议,我会加些限制并告诉你的。 - stanley
1
如果您不添加约束条件,那么在处理不同设备的自动调整大小以及每个屏幕尺寸的紧凑和扩展模式时会变得非常困难。您的代码将很快变得庞大!最好的做法是不要硬编码值,而是使用自动布局让苹果为您处理调整大小。您可以在此处阅读有关自适应用户界面的更多信息:https://developer.apple.com/design/adaptivity/! - Lucas
有人知道如何用你的视图覆盖它们吗?苹果公司在iOS10测试版iMessage中使用UIImagePickerController从文本栏中实现了这一点。 - user1681673
你可能已经给父视图添加了顶部限制条件。相反,将顶部约束条件添加到topLayoutGuide中。这解决了我遇到的完全相同的问题。 - sabiland
什么都对我没用。我正在使用 tableviewController,单元格从导航栏下方开始。 - jose920405
显示剩余3条评论
8个回答

15

这样加上一个与顶部布局指南相关的限制条件可能会有所帮助:

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

@JosipB.是被接受的答案....!但在我的Objective C代码中不起作用。我正在使用以下等效代码[self.view.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor constant:8.0].active = YES;但显然有所不同。 - jose920405
@jose920405,请查看我在ObjectiveC中的答案。 - Josip B.

4

如果你和我一样,仍然发现自动布局(Auto Layout)难以使用,那么你可以使用viewDidLayoutSubviews方法来自动调整视图大小。我有一个与你相同问题的表格视图,所以我使用了这个简单的方法来改变表格视图的顶部内容插入:

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

到目前为止,在所有iDevices上,它在纵向和横向方向上都运行良好。


4
您可以从控制器的布局指南中获取高度:
self.topLayoutGuide.length

@Dilts的演示之所以有效,是因为标签的顶部被约束到了顶部布局指南。如果它们被约束到父视图上,则它们也会在导航栏后面。

2
回答你的问题:“extra tall navbar的高度是多少”:
它是86px。
更新
关于Navbar隐藏您的UI。我做了一个快速演示,没有任何问题。
我在视图顶部添加了几个标签(就在状态栏下方,y点值为20)。接下来我添加了两个约束:左标签的前导空间和顶部空间,右标签的尾随空间和顶部空间。
这是我的结果,无论是在紧凑模式还是扩展模式下。因此,请确保将组件放置在y点值20以下,并具有一些约束条件,这样Apple将为您处理视图调整!

@stanley 我也尝试了使用UIImageView(启用了剪裁子视图和纵横比填充模式)并添加了一些简单的约束,从y点值等于20开始,它非常完美地工作了! - Lucas
1
你能提供这个项目吗?我按照你的步骤尝试了,但是对我来说没有起作用,谢谢。 - s_kirkiles
1
我正在限制到顶部布局指南,但仍然被隐藏。 - A Tyshka
2
如果您将顶部约束设置为顶部布局指南,则它将从紧凑模式到扩展模式正常工作。但是,如果扩展模式以某种方式启动,则它将无法正常工作。 - REALFREE
@Dilts:这仅适用于继承自MSMessagesAppViewControllerMessageViewController。但是当我们尝试在继承自UIViewController的ViewController中执行相同操作时,它将无法工作。 - technerd

1
如果您将顶部布局指南设置为顶部约束,则适用于MSMessagesAppViewController。但是对于UIViewControllers,它将无法工作,因为布局指南不同。
除非您真的有某种原因需要使用UIViewController类(例如:MessagesAppViewControllers在包含Obj C ++代码方面存在问题),否则请坚持使用MSMessagesAppViewController。

0
    [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分配给我放置在折叠模式下的视图的框架(减去一些用于工具栏的偏移量),但是我根据其所处的模式使用多个视图,不确定这些约束是否适用于折叠视图,因为顶部布局指南在折叠视图中仍然保持在顶部。 - danchik

0

这是Objective-C中被接受的答案

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

你能验证一下这个是否有效吗?因为我没有试过。你能在这里帮我吗:http://stackoverflow.com/questions/41707159/how-prevent-view-under-navbar-in-imessage-app-extension - jose920405
你可以查看我的问题并验证我是否做错了,请。 - jose920405

0

截至目前,使用Xcode 8.2,以上解决方案都不适用于我。

@Dilts的答案仅适用于继承自MSMessagesAppViewControllerMessageViewController。但是当我们尝试对从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
        }

    }

enter image description here

紧凑模式

enter image description here

扩展模式

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接