iOS 共享扩展中的视图布局不正确
Views not laying out correctly in iOS share extension
我有一个 NavigationVC,我在我的应用程序和共享扩展中都显示了它,它只包括一个搜索视图和一个 table 视图。在我的应用程序中,它显示正确,但在我的共享扩展中,搜索视图显示得高了 20 像素,并且被导航栏遮住了。这没有意义,因为打印出 table 视图的框架、搜索视图和 table 视图的内容插图,它们的外观不应该有差异。这是 运行 应用程序时的屏幕截图:
以及分享扩展中运行时的截图:
这是我的 initialisation/layout 代码:
override open func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.tableView)
self.view.addSubview(self.searchView)
}
override open func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.tableView.frame = self.view.bounds
var tableViewContentInsetTop: CGFloat
if let navigationBar = self.navigationController?.navigationBar {
tableViewContentInsetTop = navigationBar.frame.origin.y + navigationBar.frame.size.height
} else {
tableViewContentInsetTop = 0
}
self.searchView.frame = CGRect(
x: 0,
y: self.tableView.frame.origin.y + tableViewContentInsetTop,
width: self.tableView.frame.size.width,
height: NewConversationViewController.searchViewHeight())
tableViewContentInsetTop += self.searchView.bounds.size.height
self.tableView.contentInset.top = tableViewContentInsetTop
}
相当简单 - 它们都被添加到同一个视图中。计算出导航栏底部的 y 坐标,并将搜索视图放在那里。然后 table 视图除了其高度外,还具有搜索栏 y 的内容插图。结果,如您所料,将是他们保持一致。实际发生的是 table 视图显示正确,插入了正确的内容,但搜索栏显示的 20 像素太高。
20 像素可能与共享扩展中未提供状态栏框架(20 像素高,通常但不总是)这一事实有关。我在这两种情况下都打印了一些日志。
申请:
table view frame: (0.0, 0.0, 375.0, 667.0)
search view frame: (0.0, 64.0, 375.0, 40.0)
navigation bar bounds: (0.0, 0.0, 375.0, 44.0)
navigation bar frame: (0.0, 20.0, 375.0, 44.0)
navigation controller frame: (0.0, 0.0, 375.0, 667.0)
status bar frame: (0.0, 0.0, 375.0, 20.0)
application bounds: (0.0, 0.0, 375.0, 667.0)
table view content inset: 104.0
分享扩展:
table view frame: (0.0, 0.0, 375.0, 667.0)
search view frame: (0.0, 44.0, 375.0, 40.0)
navigation bar bounds: (0.0, 0.0, 375.0, 44.0)
navigation bar frame: (0.0, 0.0, 375.0, 44.0)
navigation controller frame: (0.0, 0.0, 375.0, 667.0)
status bar frame: (0.0, 0.0, 0.0, 0.0)
application bounds: (0.0, 0.0, 375.0, 667.0)
table view content inset: 84.0
您可以看到由于未考虑状态栏框架而导致的 20 像素差异,但这并不影响 table 视图的外观 - 仍按预期显示。我不明白为什么搜索栏会与它处于不同的相对位置。
找到解决方案:
直到调用 viewDidAppear
后才确定状态栏框架,但此时不会调用 viewWillLayoutSubviews
。所以在 viewDidAppear
中调用 setNeedsLayout
修复它。
至于为什么它会对 searchView
的布局产生不利影响而不是 tableView
,我不知道,因为它们都是常规 UIViewController 的附加属性。
我有一个 NavigationVC,我在我的应用程序和共享扩展中都显示了它,它只包括一个搜索视图和一个 table 视图。在我的应用程序中,它显示正确,但在我的共享扩展中,搜索视图显示得高了 20 像素,并且被导航栏遮住了。这没有意义,因为打印出 table 视图的框架、搜索视图和 table 视图的内容插图,它们的外观不应该有差异。这是 运行 应用程序时的屏幕截图:
以及分享扩展中运行时的截图:
这是我的 initialisation/layout 代码:
override open func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.tableView)
self.view.addSubview(self.searchView)
}
override open func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.tableView.frame = self.view.bounds
var tableViewContentInsetTop: CGFloat
if let navigationBar = self.navigationController?.navigationBar {
tableViewContentInsetTop = navigationBar.frame.origin.y + navigationBar.frame.size.height
} else {
tableViewContentInsetTop = 0
}
self.searchView.frame = CGRect(
x: 0,
y: self.tableView.frame.origin.y + tableViewContentInsetTop,
width: self.tableView.frame.size.width,
height: NewConversationViewController.searchViewHeight())
tableViewContentInsetTop += self.searchView.bounds.size.height
self.tableView.contentInset.top = tableViewContentInsetTop
}
相当简单 - 它们都被添加到同一个视图中。计算出导航栏底部的 y 坐标,并将搜索视图放在那里。然后 table 视图除了其高度外,还具有搜索栏 y 的内容插图。结果,如您所料,将是他们保持一致。实际发生的是 table 视图显示正确,插入了正确的内容,但搜索栏显示的 20 像素太高。
20 像素可能与共享扩展中未提供状态栏框架(20 像素高,通常但不总是)这一事实有关。我在这两种情况下都打印了一些日志。
申请:
table view frame: (0.0, 0.0, 375.0, 667.0)
search view frame: (0.0, 64.0, 375.0, 40.0)
navigation bar bounds: (0.0, 0.0, 375.0, 44.0)
navigation bar frame: (0.0, 20.0, 375.0, 44.0)
navigation controller frame: (0.0, 0.0, 375.0, 667.0)
status bar frame: (0.0, 0.0, 375.0, 20.0)
application bounds: (0.0, 0.0, 375.0, 667.0)
table view content inset: 104.0
分享扩展:
table view frame: (0.0, 0.0, 375.0, 667.0)
search view frame: (0.0, 44.0, 375.0, 40.0)
navigation bar bounds: (0.0, 0.0, 375.0, 44.0)
navigation bar frame: (0.0, 0.0, 375.0, 44.0)
navigation controller frame: (0.0, 0.0, 375.0, 667.0)
status bar frame: (0.0, 0.0, 0.0, 0.0)
application bounds: (0.0, 0.0, 375.0, 667.0)
table view content inset: 84.0
您可以看到由于未考虑状态栏框架而导致的 20 像素差异,但这并不影响 table 视图的外观 - 仍按预期显示。我不明白为什么搜索栏会与它处于不同的相对位置。
找到解决方案:
直到调用 viewDidAppear
后才确定状态栏框架,但此时不会调用 viewWillLayoutSubviews
。所以在 viewDidAppear
中调用 setNeedsLayout
修复它。
至于为什么它会对 searchView
的布局产生不利影响而不是 tableView
,我不知道,因为它们都是常规 UIViewController 的附加属性。