如何快速将popoverview居中
我有下面的代码来显示一个没有箭头的popoverview(对话框),这工作正常。 唯一的问题是,对话框显示在左上方(IPad)。 我想将视图集中在屏幕上。
什么更改或添加在我的下面的代码? :
func show_help(){ let storyboard = UIStoryboard(name: "Main", bundle: nil) let controller = storyboard.instantiateViewControllerWithIdentifier("Help") as! UIViewController controller.modalPresentationStyle = UIModalPresentationStyle.Popover let popoverPresentationController = controller.popoverPresentationController // result is an optional (but should not be nil if modalPresentationStyle is popover) if let _popoverPresentationController = popoverPresentationController { // set the view from which to pop up _popoverPresentationController.sourceView = self.view; _popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirection.allZeros; // present (id iPhone it is a modal automatic full screen) self.presentViewController(controller, animated: true, completion: nil) } }
其他信息
在我看来,这是链接到我的viewcontroller我设置这样的优先大小:
override func viewDidLoad() { let dialogheigth:CGFloat = self.view.frame.height * 0.5; let dialogwidth:CGFloat = self.view.frame.width * 0.5; self.preferredContentSize = CGSizeMake(dialogwidth,dialogheigth); }
您需要提供popup窗口的源代码。
从苹果文档: 源rect是在指定的视图中定位popup窗口的矩形。 将此属性与sourceView属性结合使用可指定popup窗口的锚点位置。
在你的情况下,下
_popoverPresentationController.sourceView = self.view;
加:
_popoverPresentationController.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds),0,0)
它会做的伎俩!
这是一个使用Swift 3的实现
let popover = storyboard?.instantiateViewController(withIdentifier: "popover") as! PopoverVC popover.modalPresentationStyle = UIModalPresentationStyle.popover popover.popoverPresentationController?.backgroundColor = UIColor.green popover.popoverPresentationController?.delegate = self popover.popoverPresentationController?.sourceView = self.view popover.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0) popover.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0) self.present(popover, animated: true)
根据Istvan的回答
在iOS8中,您不需要使用self.view.frame
来计算宽度和高度。
您可以使用以下方法对话框的高度和宽度:
override func viewDidLoad() { var frameSize: CGPoint = CGPointMake(UIScreen.mainScreen().bounds.size.width*0.5, UIScreen.mainScreen().bounds.size.height*0.5) self.preferredContentSize = CGSizeMake(frameSize.x,frameSize.y); }
编辑:
你也可以像下面那样设置contentSizeForViewInPopover
:
self.contentSizeForViewInPopover = CGSizeMake(320.0, 360.0)
让我知道这有助于或不?
基本上由三个步骤(iOS 8)组成:
1.-呈现的观点:
比方说,你想显示一个自定义的视图来向用户请求一个评论..这里的函数loadNibForRate()
返回从它的笔尖加载的RateDialog
的实例,但你可以用这里用任何你想要find你的UIViewController
private static func presentCustomDialog(parent: RateDialogParent) -> Bool { /// Loads the rateDialog from its xib, handled this way for further customization if desired if let rateDialog = loadNibForRate() { rateDialog.modalPresentationStyle = UIModalPresentationStyle.Popover rateDialog.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve let x = parent.view.center let sourceRectX : CGFloat //Here we check for the orientation of the device, just to know if we are on an iPad let maximumDim = max(UIScreen.mainScreen().bounds.height, UIScreen.mainScreen().bounds.width) if maximumDim == 1024 { //iPad sourceRectX = xx }else { sourceRectX = 0 } rateDialog.popoverPresentationController?.sourceView = parent.view rateDialog.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.allZeros rateDialog.popoverPresentationController?.sourceRect = CGRectMake(sourceRectX, xy, 0, 0) rateDialog.popoverPresentationController?.popoverLayoutMargins = UIEdgeInsetsMake(0, 0, 0, 0) rateDialog.popoverPresentationController?.delegate = parent rateDialogParent = parent callFunctionAsync() { parent.presentViewController(rateDialog, animated: true, completion: nil) } return true } return false }
2.-如果我们旋转我们的设备,那么popover将不知道自己在哪里重新定位,除非我们在父级
RateDialogParent
public class RateDialogParent: UIViewController, UIPopoverPresentationControllerDelegate { /** This function guarantees that the RateDialog is alwas centered at parent, it locates the RateDialog's view by searching for its tag (-555) */ public func popoverPresentationController(popoverPresentationController: UIPopoverPresentationController, willRepositionPopoverToRect rect: UnsafeMutablePointer<CGRect>, inView view: AutoreleasingUnsafeMutablePointer<UIView?>) { if popoverPresentationController.presentedViewController.view.tag == RateDialog.thisViewTag { let x = popoverPresentationController.presentingViewController.view.center let newRect = CGRectMake(xx, xy, 0, 0) rect.initialize(newRect) } } }
RateDialog
你的RateDialog
应该有一个标签设置,这只是为了避免搬迁不必要的popup,如果有更多的从RateDialogParent
class RateDialog: UIViewController { @IBOutlet weak var reviewTitle: UILabel! @IBOutlet weak var reviewMessage : UILabel! @IBOutlet weak var cancelButtonTitle: UIButton! @IBOutlet weak var remindButtonTitle : UIButton! @IBOutlet weak var rateButtonTitle : UIButton! /// For being able to locate this view static let thisViewTag = -555 override func viewDidLoad() { super.viewDidLoad() //sets the tag to identify this view self.view.tag = RateDialog.thisViewTag } }
Swift 3(Xcode 8,iOS 9)的另一种方法是:
从某处调用:
self.performSegue(withIdentifier: "showPopupSegue", sender: yourButton)
在segue之前调用的函数被触发:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let popoverPresentationController = segue.destination.popoverPresentationController { let controller = popoverPresentationController controller.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0) controller.sourceView = self.view controller.sourceRect = CGRect(x: UIScreen.main.bounds.width * 0.5 - 200, y: UIScreen.main.bounds.height * 0.5 - 100, width: 400, height: 200) segue.destination.preferredContentSize=CGSize(width: 400, height: 200) } }
请记住将故事板segue的Kind属性设置为“呈现为popup窗口”和锚定属性到您以前的视图控制器中的任何视图。
Swift 4实现:
popover.popoverPresentationController?.sourceRect = CGRect(x: view.center.x, y: view.center.y, width: 0, height: 0) popover.popoverPresentationController?.sourceView = view popover.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)