2017-09-26 4 views
0

listener 새 UIViewController가 푸시 될 때마다보고하는 종류가 필요합니다. 하나의 클래스에서 하위 클래스로 만든 다음 수퍼 viewDidLoad/viewDidAppear에서 수신하여이 작업을 수행 할 수 있습니다.하지만 여전히 하위 클래스 이름을 super에 전달해야합니다.응용 프로그램 전체에서 viewWillAppear 호출을 감지하는 수신기를 만들려고합니다.

새로운보기가 나타날 때마다 자동으로 감지하는 다른 방법이 있습니까?

여기서는 화면로드 시간 등을보고하는 logging 라이브러리에서 작업하고 있습니다. 또한 앱의 모든 버튼을 한 지점에서 듣고 싶습니다.

답변

0

Observable 패턴을 사용하는 것은 어떻습니까? 라이프 사이클 메소드의 변경 사항에 대해 appdelegate에게 알리도록 각보기 컨트롤러를 설정하십시오. 그런 다음 필요에 따라 이러한 변경 사항을 파일에 기록 할 수 있습니다.

0

내가 언급 한 것처럼 가장 좋은 방법은 view 컨트롤러를 서브 클래스 화하고 viewDidLoad/viewWillDisappear 메서드에서 로깅 파트를 수행하는 것입니다. , 원하는 것을 얻기 위해 서브 클래스 이름을 각 서브 클래스의 super로 전달할 필요는 없습니다. 재정의의 viewDidLoad에 기능을 서브 클래 싱 할의 ViewController에서

: 이것은 사용자 정보 객체에서 해당 뷰 컨트롤러 이름으로 통지를 게시 할 예정입니다

override func viewDidLoad() { 
    super.viewDidLoad() 

    NotificationCenter.default.post(name: Notification.Name(rawValue: "ViewDidLoad"), object: nil, userInfo: [ 
     "name": NSStringFromClass(type(of: self)) 
    ]) 
} 

당신이 대신 할 수있는 것은 다음과 같다. 그런 다음이 알림을 중앙 위치 (예 : AppDelegate)에 구독하고 이벤트를 처리 할 수 ​​있습니다.

0

그리 좋지 않은 구현은 모든 뷰 컨트롤러를 서브 클래스 화하여 통지를 사용하여 옵저버에 이벤트를 자동으로 보내거나 단순히 싱글 톤에서 메소드를 실행하도록하는 것입니다. 서브 클래스는 옵션이 아닌 경우

class ViewLifeCycleObserver { 
    static let shared = ViewLifeCycleObserver() 
    private(set) var viewWillAppearControllerNames: [String] = [] 
    private(set) var viewDidLoadControllerNames: [String] = [] 
    private init(){ 

    } 
    func viewDidLoad(inViewController viewController: UIViewController){ 
     viewDidLoadControllerNames.append(viewController.className) 
     print(viewController.className) 
    } 
    func viewWillAppear(inViewController viewController: UIViewController){ 
     viewWillAppearControllerNames.append(viewController.className) 
     print(viewController.className) 
    } 
} 

class ViewWillAppearObservable: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     ViewLifeCycleObserver.shared.viewDidLoad(inViewController: self) 
    } 
    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 
     ViewLifeCycleObserver.shared.viewWillAppear(inViewController: self) 
    } 
} 
extension UIViewController { 
    var className: String { 
     return NSStringFromClass(self.classForCoder).components(separatedBy: ".").last! 
    } 
} 

, 당신은 기록을 위해 각각의 모든 UIViewController에

1

ViewWillAppearObservable 클래스의 코드를 추가 할 수 있습니다, 당신은 서브 클래스 또는 지루하게 모든 UIViewController에 코드를 추가 할 필요가 없습니다 예. 대신 UIViewController의 viewDidAppear 메서드를 자신의 것으로 바꿔 넣으십시오. 당신이해야합니다

private let swizzling: (AnyClass, Selector, Selector) ->() = { forClass, originalSelector, swizzledSelector in 
    let originalMethod = class_getInstanceMethod(forClass, originalSelector) 
    let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector) 
    method_exchangeImplementations(originalMethod!, swizzledMethod!) 
} 

extension UIViewController { 

    static let classInit: Void = { 
     let originalSelector = #selector(viewDidAppear(_:)) 
     let swizzledSelector = #selector(swizzledViewDidAppear(_:)) 
     swizzling(UIViewController.self, originalSelector, swizzledSelector) 
    }() 

    @objc func swizzledViewDidAppear(_ animated: Bool) { 
     print("Add your logging logic here") 
     // Call the original viewDidAppear - using the swizzledViewDidAppear signature 
     swizzledViewDidAppear(animated) 
    } 

} 

참고 @efremidze하는 스위프트 4.

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate { 

    override init() { 
     super.init() 
     UIViewController.classInit 
    } 

원래 크레딧을 AppDelegate에의 init을 재정 의하여 스위 즐을-킥오프와 @TikhonovAlexander

하기