2017-11-20 14 views
1

나는 구조에서 매우 유사하다 3 가지 방법이있어, 나는이처럼 보이는, 일반적인 방법을 추출하고 싶습니다 :iOS Swift : 유형을 입력 매개 변수로 사용하여 일반적인 방법을 추출 하시겠습니까?

private func navigateToViewController(animated: Bool, viewControllerType: T, viewControllerNibName: String, mode: MenuMode) { ... } 

을하지만, 나는 형식 매개 변수를 처리하는 방법을 모른다, 어떤 좋은 제안? 감사!

private func navigateToEditorView(animated: Bool) { 
    self.dismiss(animated: false, completion: nil) 

    if self.editorViewController == nil { 
     let editor = EditorViewController(nibName:"EditorViewController", bundle: nil) 
     editor.exitCallBack = self.setBackgroundImage 
     self.editorViewController = editor 
    } 

    if let editor = self.editorViewController { 
     self.navigationController?.pushViewController(editor, animated: animated) 
    } 

    self.currentMenuMode = .editor 
} 

private func navigateToStorageView(animated: Bool) { 
    self.dismiss(animated: false, completion: nil) 

    if self.storageViewController == nil { 
     let storage = StorageViewController(nibName:"StorageViewController", bundle: nil) 
     storage.exitCallBack = self.setBackgroundImage 
     self.storageViewController = storage 
    } 

    if let storage = self.storageViewController { 
     self.navigationController?.pushViewController(storage, animated: animated) 
    } 

    self.currentMenuMode = .storage 
} 

private func navigateToGalleryView(animated: Bool) { 
    self.dismiss(animated: false, completion: nil) 

    if self.galleryViewController == nil { 
     let gallery = GalleryViewController(nibName:"GalleryViewController", bundle: nil) 
     gallery.exitCallBack = self.setBackgroundImage 
     self.galleryViewController = gallery 
    } 

    if let gallery = self.galleryViewController { 
     self.navigationController?.pushViewController(gallery, animated: animated) 
    } 

    self.currentMenuMode = .gallery 
} 
+0

한 문제를 하나의 일반적인 방법으로이 코드를 리팩토링 노력으로는 세 가지 다른'xxxViewController' 속성의 사용이다. – rmaddy

답변

2

I 프로토콜을 사용하는

enum MenuMode { 
    case editor 
    case storage 
    case gallery 
} 

protocol ExitCallBackHandler where Self: UIViewController { 
    var exitCallBack: (() -> Void)? { get set }; // I don't know what it is 
    var currentMenuMode: MenuMode { get } 
} 

인터페이스 마지막으로 각각의 ViewController

class EditorViewController: UIViewController, ExitCallBackHandler { 
    var exitCallBack: (() -> Void)? 
    var currentMenuMode: MenuMode { 
     return .editor 
    } 
    // ... 
} 

class StorageViewController: UIViewController, ExitCallBackHandler { 
    var exitCallBack: (() -> Void)? 
    var currentMenuMode: MenuMode { 
     return .storage 
    } 
    // ... 
} 

class GalleryViewController: UIViewController, ExitCallBackHandler { 
    var currentMenuMode: MenuMode { 
     return .gallery 
    } 
    var exitCallBack: (() -> Void)? 
    // ... 
} 

private func navigateToViewController<T: ExitCallBackHandler>(animated: Bool, viewControllerType: T.Type) { 
    self.dismiss(animated: false, completion: nil) 
    var vc = T(nibName: String(describing: viewControllerType), bundle: nil) 
    vc.exitCallBack = ... 
    self.currentMenuMode = vc.currentMenuMode 
    self.navigationController?.pushViewController(vc, animated: animated) 
} 
의 질문을 모두 처리하는 가장 좋은 방법이라고 생각 ,210

이 방법처럼 사용

navigateToViewController(animated: true, viewControllerType: StorageViewController.self) 
2

나는 당신의 기능은 단지 T을 통해 일반적인 할 필요가 생각 :

func navigateToViewController<T: UIViewController>(viewControllerType: T, nibName: String) { 
    let vc = T(nibName: nibName, bundle: nil) 
    print(vc) 
} 
1

당신의 컨트롤러이 컨트롤러가 준수 확인 프로토콜 Exitable

protocol Exitable{ 
    var exitCallBack: (()->Void)? {get set} 
} 

을 준수합니다 :

class EditorViewController: UIViewController, Exitable{ 
    var exitCallBack: (() -> Void)? 
} 
class StorageViewController: UIViewController, Exitable{ 
    var exitCallBack: (() -> Void)? 
} 
class GalleryViewController: UIViewController, Exitable{ 
    var exitCallBack: (() -> Void)? 
} 

지금 FUNC합니다

func navigateToViewController<T: UIViewController & Exitable>(viewControllerType: T?, nibName: String, withExitBlock exitBlock: @escaping()->Void, animated: Bool) { 
     var vc = T(nibName: nibName, bundle: nil) 
     vc.exitCallBack = exitBlock 
     self.navigationController?.pushViewController(vc, animated: animated) 
    }