从 iOS 8 开始 popoverController
就变成 UIPopoverPresentationController
, 由于最近的项目中用到了UIPopoverPresentationController
, 因此出于备忘的目的,在此记录下我踩过的坑。
- UIPopoverPresentationController 大小自适应
UIPopoverPresentationController
大小自适应可以通过修改UITableViewController
的preferredContentSize
属性来进行实现,首先在UITableViewController
代码文件中,override 三个方法,如下:
override func viewWillAppear() {
self.tableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
}
override func observerValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
self.preferredContentSize = tableView.contentSize
}
override func viewWillDisappear(_ animated: Bool) {
tableView.removeObserver(self, forKeyPath: "contentSize")
}
这里需要注意只能 override viewWillAppear
, viewWillDisappear
两个方法,而不能 override viewDidAppear
, viewDidDisappear
两个方法,因为会抛出it is not registered as an observer
错误,经过查阅 Apple Docs, 程序只会在view全部可见时才会添加 Observer, 因此,只有在viewWillAppear
时添加 Observer 才会成功添加,这样在 removeObserver 的时候才不会出错。
- UIPopoverPresentationController 展示时 UINavigationBarItems 可以被点击
当我们使用UIPopoverPresentationController
时,会发现popover窗口在显示时,UINavigationBarItems 可以被点击,这就很不好了,因为这会使我们的 App 看上去很奇怪,因此需要将UIPopoverPresentationController
的passthroughViews
属性设定为nil
,代码如下:
// 相关属性的设定
let popOver = viewController.popOverPresentationController
viewController.isModalInPopover = false
popOver?.permittedArrowDirections = .up
popOver?.barButtonItem = self.navigationItem.rightBarButtonItem
popOver?.delegate = self
// 使用多线程将 passthroughViews 属性设定为 nil
present(viewController, animated: true) { () -> Void in
DispatchQueue.main.async { () -> Void in
popOver?.passthroughViews = nil
}
}