iOS 8 - UIPopoverPresentationController移动弹出窗口

ang*_*boy 20 popover ios8

我正在寻找一种有效的方法来使用新的uipopoverpresentationcontroller重新定位一个popover.我已经成功地呈现了弹出窗口,现在我想移动它而不会解散并再次呈现.我在使用该功能时遇到问题:

(void)popoverPresentationController:(UIPopoverPresentationController *)popoverPresentationController
      willRepositionPopoverToRect:(inout CGRect *)rect
                           inView:(inout UIView **)view
Run Code Online (Sandbox Code Playgroud)

我知道这是游戏的早期,但任何人都有一个如何有效地做到这一点的例子,如果你和我分享,我将不胜感激.提前致谢.

小智 16

不幸的是,这个hacky解决方法是我发现的唯一解决方案:

[vc.popoverPresentationController setSourceRect:newSourceRect];
[vc setPreferredContentSize:CGRectInset(vc.view.frame, -0.01, 0.0).size];
Run Code Online (Sandbox Code Playgroud)

这会暂时更改显示视图的内容大小,从而导致弹出窗口和箭头重新定位.暂时改变大小不可见.

这似乎是苹果需要解决的一个问题 - 当它已经呈现一个弹出窗口(没有这个解决方法)时,改变sourceView或者sourceRect属性UIPopoverPresentationController什么都不做.

希望这也适合你!


cho*_*own 7

我很幸运使用,containerView?.setNeedsLayout()containerView?.layoutIfNeeded()在更改了sourceRect的后popoverPresentationController,像这样:

func movePopoverTo(_ newRect: CGRect) {
    let popover = self.presentedViewController as? MyPopoverViewController {
        popover.popoverPresentationController?.sourceRect = newRect
        popover.popoverPresentationController?.containerView?.setNeedsLayout()
        popover.popoverPresentationController?.containerView?.layoutIfNeeded()
    }
}
Run Code Online (Sandbox Code Playgroud)

甚至让popover跟随tableView单元而无需更改任何内容:

class MyTableViewController: UITableViewController {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "MyPopoverSegue" {
            guard let controller = segue.destination as? MyPopoverViewController else { fatalError("Expected destination controller to be a 'MyPopoverViewController'!") }
            guard let popoverPresentationController = controller.popoverPresentationController else { fatalError("No popoverPresentationController!") }
            guard let rowIndexPath = sender as? IndexPath else { fatalError("Expected sender to be an 'IndexPath'!") }
            guard myData.count > rowIndexPath.row else { fatalError("Index (\(rowIndexPath.row)) Out Of Bounds for array (count: \(myData.count))!") }
            if self.presentedViewController is MyPopoverViewController {
                self.presentedViewController?.dismiss(animated: false)
            }
            popoverPresentationController.sourceView = self.tableView
            popoverPresentationController.sourceRect = self.tableView.rectForRow(at: rowIndexPath)
            popoverPresentationController.passthroughViews = [self.tableView]
            controller.configure(myData[rowIndexPath.row])
        }
        super.prepare(for: segue, sender: sender)
    }
}

// MARK: - UIScrollViewDelegate

extension MyTableViewController {
    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if let popover = self.presentedViewController as? MyPopoverViewController {
            popover.popoverPresentationController?.containerView?.setNeedsLayout()
            popover.popoverPresentationController?.containerView?.layoutIfNeeded()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)