[英]Use internal func from a class to another class in swift
我有个人资料课程和设置课程
配置文件类包含一个内部函数
class Profile: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
internal func profileSelectFromGallery(sender: Profile){
let myPickerController = UIImagePickerController()
myPickerController.delegate = sender;
myPickerController.sourceType =
UIImagePickerControllerSourceType.PhotoLibrary
sender.presentViewController(myPickerController, animated:true, completion: nil)
}
}
我想在设置类中使用profileSelectFromGallery,下面有两次尝试
class SettingsVC: UITableViewController {
// I will call this private function on a click events
private func selectFromGallery(){
// let profile = Profile()
// profile.profileSelectFromGallery(self)
Profile.profileSelectFromGallery(self)
}
}
上面的代码导致Cannot convert value of type 'SettingsVC' to expected argument type 'Profile'
因为profileSelectFromGallery
需要一个类Profile
的参数,所以我要做的是更改发送方,以便可以从我的任何类中使用它,并且不只是我的个人资料课 。
因此,问题在于您无法将SettingsVC
转换为Profile
。 如果您查看方法签名,将会看到它需要一个Profile
:
internal func profileSelectFromGallery(sender: Profile)
您正在尝试在selectFromGallery()
传递SettingVC
在profileSelectFromGallery
内部,您希望发送方既是UIViewController
又是UIImagePickerControllerDelegate
。 您可以通过以下几种方法进行操作:
最简单的是更改方法签名。 您将执行以下操作:
internal func profileSelectFromGallery(sender: UIImagePickerControllerDelegate){
guard let vc = sender as? UIViewController else {
return
}
let myPickerController = UIImagePickerController()
myPickerController.delegate = sender;
myPickerController.sourceType =
UIImagePickerControllerSourceType.PhotoLibrary
vc.presentViewController(myPickerController, animated:true, completion: nil)
}
这里有presentViewController
:将sender
更改为适当的委托方法,并通过guard
声明将其presentViewController
为presentViewController
调用的VC。
做到这一点的更棒的方法是使用协议扩展!
extension UIImagePickerControllerDelegate where Self: UIViewController, Self: UINavigationControllerDelegate {
func profileSelectFromGallery() {
let myPickerController = UIImagePickerController()
myPickerController.delegate = self
myPickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(myPickerController, animated:true, completion: nil)
}
}
基本上,我在这里所做的就是为每个UIImagePickerControllerDelegate
添加一个方法,即UIViewController
和UINAvigationControllerDelegate
。 这意味着我可以在Profile和SettingVC上都调用它(一旦您将必要的委托添加到SettingVC)。 您需要做的只是:
let profile = Profile()
profile.profileSelectFromGallery()
let settingVC = SettingVC()
settingVC.profileSelectFromGallery()
将新协议声明为:
protocol PickerProtocol : UIImagePickerControllerDelegate, UINavigationControllerDelegate {
}
现在,您的Profile类将如下所示:
class Profile: UIViewController, PickerProtocol {
//Option 1
internal func profileSelectFromGallery(contoller: UIViewController, pickerProtocol: PickerProtocol){
let myPickerController = UIImagePickerController()
myPickerController.delegate = pickerProtocol
myPickerController.sourceType =
UIImagePickerControllerSourceType.PhotoLibrary
contoller.presentViewController(myPickerController, animated:true, completion: nil)
}
//Option 2
internal func profileSelectFromGalleryOption2(sender : UIViewController? ) {
var viewContoller : UIViewController = self
if let unwrappedSender = sender {
viewContoller = unwrappedSender
}
let myPickerController = UIImagePickerController()
if let pickerProtocol = viewContoller as? PickerProtocol {
myPickerController.delegate = pickerProtocol
} else {
myPickerController.delegate = self //Assign self as default
}
myPickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
viewContoller.presentViewController(myPickerController, animated:true, completion: nil)
}
}
class SettingsVC1: UITableViewController {
// I will call this private function on a click events
private func selectFromGallery(){
let profile = Profile()
profile.profileSelectFromGallery(self, pickerProtocol:profile)
profile.profileSelectFromGalleryOption2(self)
//Or
profile.profileSelectFromGalleryOption2(nil)//profile itself delegate and presenting controller
}
}
// 要么
class SettingsVC2: UITableViewController, PickerProtocol {
// I will call this private function on a click events
private func selectFromGallery(){
let profile = Profile()
profile.profileSelectFromGallery(self, pickerProtocol:self)
profile.profileSelectFromGalleryOption2(self)
//Or
profile.profileSelectFromGalleryOption2(nil)//profile itself delegate and presenting controller
}
}
我会这样使用POP(面向协议的程序设计):
protocol SelectorProtocol: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
}
extension SelectorProtocol where Self: UIViewController {
func profileSelectFromGallery() {
let myPickerController = UIImagePickerController()
myPickerController.delegate = self;
myPickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(myPickerController, animated:true, completion: nil)
}
}
class Profile: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate, SelectorProtocol {
func foo() {
profileSelectFromGallery()
}
}
class SettingsVC: UITableViewController, SelectorProtocol {
// I will call this private function on a click events
private func selectFromGallery(){
profileSelectFromGallery()
}
}
您正在尝试静态调用profileSelectFromGallery:
即使它是一个实例方法。
尝试将方法定义更改为:
internal static func profileSelectFromGallery(sender: Profile){
至于能够将任何类用作委托,请创建自定义Protocol
并确保sender
符合此协议。 有关更多信息,请参见此处(特别是标题为Protocols
的标题): http : //www.raywenderlich.com/115300/swift-2-tutorial-part-3-tuples-protocols-delegates-and-table-views
也许以下方法会起作用:
class SettingsVC: UITableViewController {
// I will call this private function on a click events
private func selectFromGallery(){
let prof = Profile()
prof.profileSelectFromGallery(prof)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.