Swift 1.2 在 iOS 8 上的全局弹出框功能
Global Popover Function in Swift 1.2 on iOS 8
我在我的应用程序中使用了这个函数,创建一个全局函数会很好:
class CustomReportVC: UIViewController, UIAdaptivePresentationControllerDelegate, UIPopoverPresentationControllerDelegate {
func showPicker(pickerValues:[String], field:UITextField) -> AnyPickerVC{
//Set up modal
let storyboard = UIStoryboard(name: "Popovers", bundle: nil)
let modal = storyboard.instantiateViewControllerWithIdentifier("AnyPickerModal") as! AnyPickerVC
modal.modalPresentationStyle = UIModalPresentationStyle.Popover
let pc = modal.popoverPresentationController
pc?.permittedArrowDirections = .Down
pc?.sourceView = field
pc?.sourceRect = field.bounds
modal.preferredContentSize = CGSizeMake(300,180)
pc?.delegate = self
//Pass in data
modal.data = pickerValues
//Set the value from within the picker controller
modal.passDataToParent = { (value) in
field.text = value
}
return modal
}
//Required for the popover
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .None
}
}
我 运行 遇到的问题是 pc?.delegate = self
。由于 CustomReportVC
符合 UIPopoverPresentationControllerDelegate
,因此可以正常工作。
但是一旦我尝试将其创建为符合此协议的 class 之外的全局函数,我就会收到错误消息:
func globalShowPicker(pickerValues:[String], field:UITextField, controller:UIViewController) -> AnyPickerVC{
//...
pc?.delegate = controller //<-- ( ! ) Type UIViewController does not conform to UIPopoverPresentationControllerDelegate
}
不管我把controller
做成UIViewController
还是AnyObject
,都不符合。有没有办法以某种方式将协议符合性传递给全局函数?
知道如何解决这个问题吗?谢谢。 :)
尝试添加一个继承自它们的新 class。像这样。
class PopoverController: UIViewController, UIPopoverPresentationControllerDelegate {
}
然后,将函数切换成这样。
func globalShowPicker(pickerValues:[String], field:UITextField, controller: PopoverController) -> AnyPickerVC{
//...
pc?.delegate = controller
}
使您的全局函数通用以指定它仅适用于某些 类型的 UIViewController。在此示例中,T
可以采用任何 UIViewController 类型的值,该类型也符合列出的其他协议。
func globalShowPicker< T: UIViewController where
T: UIPopoverPresentationControllerDelegate,
T: UIAdaptivePresentationControllerDelegate >
(pickerValues:[String], field:UITextField, controller: T) -> AnyPickerVC
{
//...
pc?.delegate = controller
return blah
}
确实有点长,而且我还没有找到缩进所有约束的最佳方法。但它有效。
是这样的吗?
self.presentViewController(pc, animated: true, completion: nil)
顺便说一句,如果你正在做通用,你不能像 iPhone 那样呈现 iPad UIActivityViewController。您需要按照 Apple 建议的设计指南将其呈现在弹出窗口中。
或者举个例子
@IBAction func shareButtonClicked(sender: UIButton)
{
let textToShare = "Text"
if let myWebsite = NSURL(string: "http://www.example.com/")
{
let objectsToShare = [textToShare, myWebsite]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
var nav = UINavigationController(rootViewController: activityVC)
nav.modalPresentationStyle = UIModalPresentationStyle.Popover
var popover = nav.popoverPresentationController as UIPopoverPresentationController!
activityVC.preferredContentSize = CGSizeMake(500,600)
popover.sourceView = self.view
popover.sourceRect = CGRectMake(100,100,0,0)
self.presentViewController(nav, animated: true, completion: nil)
}
}
class MyViewController : UIViewController, UIPopoverPresentationControllerDelegate {
//code here
}
您可以像这样在函数中将委托作为参数传递:
class CustomReportVC: UIViewController, UIAdaptivePresentationControllerDelegate, UIPopoverPresentationControllerDelegate {
class func showPicker(pickerValues:[String], field:UITextField, delegate: UIPopoverPresentationControllerDelegate) -> UIViewController {
//Set up modal
let storyboard = UIStoryboard(name: "Popovers", bundle: nil)
let modal = storyboard.instantiateViewControllerWithIdentifier("AnyPickerModal") as! UIViewController
modal.modalPresentationStyle = UIModalPresentationStyle.Popover
let pc = modal.popoverPresentationController
pc?.permittedArrowDirections = .Down
pc?.sourceView = field
pc?.sourceRect = field.bounds
modal.preferredContentSize = CGSizeMake(300,180)
pc?.delegate = delegate
//Pass in data
modal.data = pickerValues
//Set the value from within the picker controller
modal.passDataToParent = { (value) in
field.text = value
}
return modal
}
//Required for the popover
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .None
}
}
最后你必须有一个符合协议的视图控制器实例,但这样你就可以拥有全局函数,就像你想要的一样,并在符合协议的视图控制器中传递自指针协议 "UIPopoverPresentationControllerDelegate":
CustomReportVC.showPicker(pickerValues:....., delegate: self)
我在我的应用程序中使用了这个函数,创建一个全局函数会很好:
class CustomReportVC: UIViewController, UIAdaptivePresentationControllerDelegate, UIPopoverPresentationControllerDelegate {
func showPicker(pickerValues:[String], field:UITextField) -> AnyPickerVC{
//Set up modal
let storyboard = UIStoryboard(name: "Popovers", bundle: nil)
let modal = storyboard.instantiateViewControllerWithIdentifier("AnyPickerModal") as! AnyPickerVC
modal.modalPresentationStyle = UIModalPresentationStyle.Popover
let pc = modal.popoverPresentationController
pc?.permittedArrowDirections = .Down
pc?.sourceView = field
pc?.sourceRect = field.bounds
modal.preferredContentSize = CGSizeMake(300,180)
pc?.delegate = self
//Pass in data
modal.data = pickerValues
//Set the value from within the picker controller
modal.passDataToParent = { (value) in
field.text = value
}
return modal
}
//Required for the popover
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .None
}
}
我 运行 遇到的问题是 pc?.delegate = self
。由于 CustomReportVC
符合 UIPopoverPresentationControllerDelegate
,因此可以正常工作。
但是一旦我尝试将其创建为符合此协议的 class 之外的全局函数,我就会收到错误消息:
func globalShowPicker(pickerValues:[String], field:UITextField, controller:UIViewController) -> AnyPickerVC{
//...
pc?.delegate = controller //<-- ( ! ) Type UIViewController does not conform to UIPopoverPresentationControllerDelegate
}
不管我把controller
做成UIViewController
还是AnyObject
,都不符合。有没有办法以某种方式将协议符合性传递给全局函数?
知道如何解决这个问题吗?谢谢。 :)
尝试添加一个继承自它们的新 class。像这样。
class PopoverController: UIViewController, UIPopoverPresentationControllerDelegate {
}
然后,将函数切换成这样。
func globalShowPicker(pickerValues:[String], field:UITextField, controller: PopoverController) -> AnyPickerVC{
//...
pc?.delegate = controller
}
使您的全局函数通用以指定它仅适用于某些 类型的 UIViewController。在此示例中,T
可以采用任何 UIViewController 类型的值,该类型也符合列出的其他协议。
func globalShowPicker< T: UIViewController where
T: UIPopoverPresentationControllerDelegate,
T: UIAdaptivePresentationControllerDelegate >
(pickerValues:[String], field:UITextField, controller: T) -> AnyPickerVC
{
//...
pc?.delegate = controller
return blah
}
确实有点长,而且我还没有找到缩进所有约束的最佳方法。但它有效。
是这样的吗?
self.presentViewController(pc, animated: true, completion: nil)
顺便说一句,如果你正在做通用,你不能像 iPhone 那样呈现 iPad UIActivityViewController。您需要按照 Apple 建议的设计指南将其呈现在弹出窗口中。
或者举个例子
@IBAction func shareButtonClicked(sender: UIButton)
{
let textToShare = "Text"
if let myWebsite = NSURL(string: "http://www.example.com/")
{
let objectsToShare = [textToShare, myWebsite]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
var nav = UINavigationController(rootViewController: activityVC)
nav.modalPresentationStyle = UIModalPresentationStyle.Popover
var popover = nav.popoverPresentationController as UIPopoverPresentationController!
activityVC.preferredContentSize = CGSizeMake(500,600)
popover.sourceView = self.view
popover.sourceRect = CGRectMake(100,100,0,0)
self.presentViewController(nav, animated: true, completion: nil)
}
}
class MyViewController : UIViewController, UIPopoverPresentationControllerDelegate {
//code here
}
您可以像这样在函数中将委托作为参数传递:
class CustomReportVC: UIViewController, UIAdaptivePresentationControllerDelegate, UIPopoverPresentationControllerDelegate {
class func showPicker(pickerValues:[String], field:UITextField, delegate: UIPopoverPresentationControllerDelegate) -> UIViewController {
//Set up modal
let storyboard = UIStoryboard(name: "Popovers", bundle: nil)
let modal = storyboard.instantiateViewControllerWithIdentifier("AnyPickerModal") as! UIViewController
modal.modalPresentationStyle = UIModalPresentationStyle.Popover
let pc = modal.popoverPresentationController
pc?.permittedArrowDirections = .Down
pc?.sourceView = field
pc?.sourceRect = field.bounds
modal.preferredContentSize = CGSizeMake(300,180)
pc?.delegate = delegate
//Pass in data
modal.data = pickerValues
//Set the value from within the picker controller
modal.passDataToParent = { (value) in
field.text = value
}
return modal
}
//Required for the popover
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .None
}
}
最后你必须有一个符合协议的视图控制器实例,但这样你就可以拥有全局函数,就像你想要的一样,并在符合协议的视图控制器中传递自指针协议 "UIPopoverPresentationControllerDelegate":
CustomReportVC.showPicker(pickerValues:....., delegate: self)