在swift中使用类中的内部函数到另一个类

时间:2016-01-20 04:10:27

标签: ios swift swift2

我有个人资料类和设置类

profile类包含内部函数

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的参数,所以我想要做的是更改发件人,以便我可以使用任何我的课程,而不仅仅是我的个人资料课程

5 个答案:

答案 0 :(得分:5)

问题是您无法将SettingsVC转换为Profile。如果您查看方法签名,您会看到它期待Profile

internal func profileSelectFromGallery(sender: Profile)

您正试图在selectFromGallery()

中传入SettingVC

profileSelectFromGallery内,您希望发件人同时为UIViewControllerUIImagePickerControllerDelegate。有几种方法可以做到这一点:

最简单的方法是更改​​方法签名。你会做这样的事情:

   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主要内容:sender更改为正确的委托方法,并且guard语句将其转换为VC以进行presentViewController调用。

更棒的方法是使用协议扩展!

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添加一个方法,即UIViewControllerUINAvigationControllerDelegate。这意味着我可以在Profile和SettingVC上调用它(一旦你将必要的委托添加到SettingVC)。您需要做的就是:

let profile = Profile()
profile.profileSelectFromGallery()

let settingVC = SettingVC()
settingVC.profileSelectFromGallery()

答案 1 :(得分:3)

将新协议声明为:

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

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

答案 2 :(得分:1)

我会像这样使用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()
    }
}

答案 3 :(得分:0)

您尝试静态调用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

答案 4 :(得分:0)

或许以下方法可行:

   class SettingsVC: UITableViewController {
   // I will call this private function on a click events
   private func selectFromGallery(){
       let prof = Profile()
       prof.profileSelectFromGallery(prof)
   }
}