我有个人资料类和设置类
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
的参数,所以我想要做的是更改发件人,以便我可以使用任何我的课程,而不仅仅是我的个人资料课程。
答案 0 :(得分:5)
问题是您无法将SettingsVC
转换为Profile
。如果您查看方法签名,您会看到它期待Profile
:
internal func profileSelectFromGallery(sender: Profile)
您正试图在selectFromGallery()
在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)
}
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
添加一个方法,即UIViewController
和UINAvigationControllerDelegate
。这意味着我可以在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)
}
}