简体   繁体   English

快速使用从一个类到另一个类的内部函数

[英]Use internal func from a class to another class in swift

I have a profile class and settings class 我有个人资料课程和设置课程

profile class contains an internal function 配置文件类包含一个内部函数

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)
    }
}

I want to use profileSelectFromGallery in setting class and I have two tries below 我想在设置类中使用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)

   }
}

The above codes results into Cannot convert value of type 'SettingsVC' to expected argument type 'Profile' since profileSelectFromGallery needs a parameter of a class Profile so what i want to do is change sender so that i can use it from any of my class and not just my Profile class . 上面的代码导致Cannot convert value of type 'SettingsVC' to expected argument type 'Profile'因为profileSelectFromGallery需要一个类Profile的参数,所以我要做的是更改发送方,以便可以从我的任何类中使用它,并且不只是我的个人资料课

So the problem is that you can't convert a SettingsVC into a Profile . 因此,问题在于您无法将SettingsVC转换为Profile If you look at the method signature you'll see it's expecting a Profile : 如果您查看方法签名,将会看到它需要一个Profile

internal func profileSelectFromGallery(sender: Profile)

You are trying to pass in a SettingVC in selectFromGallery() 您正在尝试在selectFromGallery()传递SettingVC

Inside profileSelectFromGallery you want the sender to be both a UIViewController and a UIImagePickerControllerDelegate . profileSelectFromGallery内部,您希望发送方既是UIViewController又是UIImagePickerControllerDelegate There's a couple ways you could do this: 您可以通过以下几种方法进行操作:

The simplest is to change the method signature. 最简单的是更改方法签名。 You'd do something like this: 您将执行以下操作:

   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)
    }

Theres 2 main things here: sender is changed to the proper delegate method, and theres a guard statement to cast it to a VC for the presentViewController call. 这里有presentViewController :将sender更改为适当的委托方法,并通过guard声明将其presentViewControllerpresentViewController调用的VC。

The much more awesome way to do this is to use protocol extensions! 做到这一点的更棒的方法是使用协议扩展!

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)
    }
}

Basically what I'm doing here is adding a method for every UIImagePickerControllerDelegate thats also an UIViewController and an UINAvigationControllerDelegate . 基本上,我在这里所做的就是为每个UIImagePickerControllerDelegate添加一个方法,即UIViewControllerUINAvigationControllerDelegate This means that I can call it on both Profile and SettingVC (once you add the necessary delegates to SettingVC). 这意味着我可以在Profile和SettingVC上都调用它(一旦您将必要的委托添加到SettingVC)。 All you would need to do is: 您需要做的只是:

let profile = Profile()
profile.profileSelectFromGallery()

let settingVC = SettingVC()
settingVC.profileSelectFromGallery()

Declare new protocol as: 将新协议声明为:

protocol PickerProtocol : UIImagePickerControllerDelegate, UINavigationControllerDelegate {

} }

Now your Profile class will look like: 现在,您的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
    }
}

// OR // 要么

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
    }
}

I would use POP (protocol oriented programming) like this: 我会这样使用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()
    }
}

You are trying to statically call profileSelectFromGallery: even though it is an instance method. 您正在尝试静态调用profileSelectFromGallery:即使它是一个实例方法。

Try changing the method definition to: 尝试将方法定义更改为:

internal static func profileSelectFromGallery(sender: Profile){

As for being able to use any class as a delegate, create a custom Protocol and ensure that the sender conforms to this protocol. 至于能够将任何类用作委托,请创建自定义Protocol并确保sender符合此协议。 See here (specifically the heading titled Protocols ) for more information: http://www.raywenderlich.com/115300/swift-2-tutorial-part-3-tuples-protocols-delegates-and-table-views 有关更多信息,请参见此处(特别是标题为Protocols的标题): http : //www.raywenderlich.com/115300/swift-2-tutorial-part-3-tuples-protocols-delegates-and-table-views

perhaps the following will work: 也许以下方法会起作用:

   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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM