ios - 当弹出窗口的源 View 在 Swift 中更改时,如何更新弹出窗口的布局(位置)?

标签 ios swift autolayout uikit uipopoverpresentationcontroller

我想更新弹出窗口的布局,我已经尝试使用 setNeedsLayout()layoutIfNeeded() 方法,但找不到解决方案。

我有一个简单的屏幕,有 4 个调用弹出窗口的按钮,弹出窗口内有 2 个额外的按钮:

  1. 按钮 -> 隐藏按钮 3,并将按钮 1 和按钮 2 向左移动。
  2. 重新定位 -> 将弹出窗口的源 View 从按钮 1/2/3/4(发送者)更改为按钮 4。 Picture of the layout

我遇到的问题是我无法更新/刷新屏幕,并且弹出窗口始终指向以前的源 View 位置。 Picture of the popover

不知何故,我需要一种更新 View 的方法,该方法比 layoutIfNeeded() 更强大,因为如果屏幕从纵向/横向更改,弹出窗口会自动更改。 Here I changed portrait/landscape/portrait

项目的 GitHub。 GitHub

使用的代码如下:

class ViewController: UIViewController, ButtonDidDisappearDelegate {

    @IBOutlet weak var button1: UIButton!
    @IBOutlet weak var button2: UIButton!
    @IBOutlet weak var button3: UIButton!
    @IBOutlet weak var button4: UIButton!

    @IBOutlet weak var constrain2: NSLayoutConstraint!

    var popVC: PopVC?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func buttonPopover(_ sender: UIButton) {
        configureAndPresentPopover(from: sender)
    }

    func buttonDisappear() {
        self.constrain2.constant = 100
        self.button3.isHidden = !self.button3.isHidden

        if !self.button3.isHidden {
            self.constrain2.constant = 10
        }
    }

    func repositionPopover() {
        DispatchQueue.main.async {
            if let popVC = self.popVC {
                self.self.popoverPresentationController(popVC.popoverPresentationController!, willRepositionPopoverTo: self.button4.bounds, in: self.button4)
            }
            self.view.setNeedsLayout()
            self.view.layoutIfNeeded()
        }
    }
}

extension ViewController: UIPopoverPresentationControllerDelegate {

    func configureAndPresentPopover(from sender: UIButton) {

        popVC = storyboard?.instantiateViewController(withIdentifier: "popVC") as? PopVC

        guard let popVC = popVC else {
            return
        }

        popVC.popOverDelegate = self
        popVC.modalPresentationStyle = .popover

        let popOverVC = popVC.popoverPresentationController
        popOverVC?.delegate = self
        popOverVC?.sourceView = sender
        popOverVC?.sourceRect = sender.bounds
        popVC.preferredContentSize = CGSize(width: 300, height: 60)
        popOverVC?.permittedArrowDirections = .down

        self.present(popVC, animated: true)
    }

    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        return .none
    }

    func popoverPresentationController(_ popoverPresentationController: UIPopoverPresentationController,
                                       willRepositionPopoverTo rect: CGRect,
                                       in view: UIView) {
        popoverPresentationController.sourceView = view
        popoverPresentationController.sourceRect = rect
    }
}

和弹出窗口 Controller :

protocol ButtonDidDisappearDelegate: class {
    func configureAndPresentPopover(from sender: UIButton)
    func buttonDisappear()
    func repositionPopover()
}

class PopVC: UIViewController {

    weak var popOverDelegate: ButtonDidDisappearDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
    }


    @IBOutlet weak var popoverButton: UIButton!

    @IBAction func popoverAction(_ sender: Any) {
        popOverDelegate?.buttonDisappear()
        DispatchQueue.main.async {
            self.view.setNeedsLayout()
            self.view.layoutIfNeeded()
        }
    }

    @IBAction func reposition(_ sender: Any) {
        popOverDelegate?.repositionPopover()
    }
}

最佳答案

您需要指定箭头的新位置并询问演示 Controller View 的布局,而不仅仅是演示的 View 。

尝试:

func repositionPopover() {
    let popOverController = presentedViewController?.presentationController as? UIPopoverPresentationController
    popOverController?.sourceView = button4
    popOverController?.containerView?.setNeedsLayout()
    popOverController?.containerView?.layoutIfNeeded()
}

关于ios - 当弹出窗口的源 View 在 Swift 中更改时,如何更新弹出窗口的布局(位置)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50203570/

相关文章:

swift - UIButtons 在所有设备上的形状都不正确

ios - 带有多个内衬标签的 estimatedRowHeight 导致单元格剪裁

iOS Facebook SDK 错误语言

ios - 如何使用swift2以编程方式获取Apple Watch序列号?

javascript - 如何使用 phonegap 在 iOS 应用程序中打开网页?

ios - 无法将 @IBOutlet 从 swift 文件拖到 Xcode 7.2 中的 Storyboard ViewController

ios - captureStillImageAsynchronously 在特定时间不起作用

ios - 如何设置对类成员的弱引用,例如回调方法?

ios - 断言失败 - 具有自动布局和自定义 UICollectionViewFlowLayout 的 UITableViewCell 内的 CollectionView

swift - 在 Swift 中实现一个协议(protocol)