gpt4 book ai didi

swift - 作为弹出窗口呈现的 UIViewController 可以是它自己的 popoverPresentationController 委托(delegate)吗?

转载 作者:行者123 更新时间:2023-11-28 06:14:49 28 4
gpt4 key购买 nike

在下面显示的项目中,有一个 InitialViewController,它有一个标记为“Show Popover”的按钮。当点击该按钮时,应用程序应该将第二个 View Controller (PopoverViewController) 显示为弹出窗口。第二个 View Controller 只有一个标签,上面写着“Popover!”。

storyboard image

如果 InitialViewController 负责实例化 PopoverViewController,检索 popoverPresentationController 然后设置 popoverPresentationController 的 delegate 到自身(到 InitialViewController)。您可以在下面看到结果:

functiong app when delegation occurs in InitialViewController

但是,为了最大限度地提高可重用性,如果 InitialViewController 不需要了解有关如何委派演示 Controller 的任何信息,那就太好了。我认为 PopoverViewController 应该可以将自己设置为 popoverPresentationController 的 delegate。我已经在 PopoverViewControllerviewDidLoadviewWillAppear 函数中试过这个。但是,PopoverViewController 在这两种情况下都是模态显示的,如下所示:

enter image description here

所有代码都包含在 InitialViewControllerPopoverViewController 中。 InitialViewController失败 版本中使用的代码如下所示:

import UIKit

// MARK: - UIViewController subclass

class InitialViewController: UIViewController {

struct Lets {
static let storyboardName = "Main"
static let popoverStoryboardID = "Popover View Controller"
}

@IBAction func showPopoverButton(_ sender: UIButton) {

// instantiate & present the popover view controller
let storyboard = UIStoryboard(name: Lets.storyboardName,
bundle: nil )
let popoverViewController =
storyboard.instantiateViewController(withIdentifier: Lets.popoverStoryboardID )
popoverViewController.modalPresentationStyle = .popover
guard let popoverPresenter = popoverViewController.popoverPresentationController
else {
fatalError( "could not retrieve a pointer to the 'popoverPresentationController' property of popoverViewController")
}
present(popoverViewController,
animated: true,
completion: nil )

// Retrieve and configure UIPopoverPresentationController
// after presentation (per
// https://developer.apple.com/documentation/uikit/uipopoverpresentationcontroller)

popoverPresenter.permittedArrowDirections = .any
let button = sender
popoverPresenter.sourceView = button
popoverPresenter.sourceRect = button.bounds

}
}

failingPopoverViewController中的代码如下所示:

import UIKit


// MARK: - main UIViewController subclass

class PopoverViewController: UIViewController {

// MARK: API
var factorForMarginsAroundButton: CGFloat = 1.2

// MARK: outlets and actions
@IBOutlet weak var popoverLabel: UILabel!

// MARK: lifecycle

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear( animated )

// set the preferred size for popover presentations
let labelSize =
popoverLabel.systemLayoutSizeFitting( UILayoutFittingCompressedSize )
let labelWithMargins =
CGSize(width: labelSize.width * factorForMarginsAroundButton,
height: labelSize.height * factorForMarginsAroundButton )
preferredContentSize = labelWithMargins

// set the delegate for the popoverPresentationController to self
popoverPresentationController?.delegate = self

}
}
// MARK: - UIPopoverPresentationControllerDelegate
// (inherits from protocol UIAdaptivePresentationControllerDelegate)

extension PopoverViewController: UIPopoverPresentationControllerDelegate
{
func adaptivePresentationStyle(for controller: UIPresentationController,
traitCollection: UITraitCollection)
-> UIModalPresentationStyle{
return .none
}
}

作为弹出窗口呈现的 View Controller 是否有可能成为它自己的 popoverPresentationController 的委托(delegate)?

我正在使用 Xcode 8.0、Swift 3.1,目标是 iOS 10.0

最佳答案

这当然是可能的。您正在处理时间问题。您需要在 viewWillAppear 之前设置委托(delegate)。不幸的是,没有方便的 View 生命周期函数来插入赋值,所以我改为这样做。

在您的 PopoverViewController 类中,在覆盖的 getter 中分配委托(delegate)。如果您愿意,可以使分配有条件。这创建了一种永久关系,因此其他代码永远不会通过分配委托(delegate)来“覆盖”委托(delegate)。

override var popoverPresentationController: UIPopoverPresentationController? {
get {
let ppc = super.popoverPresentationController
ppc?.delegate = self
return ppc
}
}

关于swift - 作为弹出窗口呈现的 UIViewController 可以是它自己的 popoverPresentationController 委托(delegate)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45469066/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com