2016-05-04 4 views
1

Учитывая экземпляр класса, как я могу наблюдать изменение свойства? Для например, я построение SDK, который инициализирует вид чата принимающего приложения, чтобы обеспечить более широкую функциональность с простой реализацией любым, который выглядит как:Наблюдать изменение свойства экземпляра класса

sdk.initialize(chatView)

В этой инициализации функции, мне нужно отслеживать приложения хозяина chat-view's hidden, чтобы совпадало представление SDK.

+0

'hidden'? дайте более подробную информацию, покажите код – Wain

+0

Вы имеете в виду, когда свойство в классе «А» меняет значение, что-то происходит в классе «В»? –

+0

@Peter M - Точно. –

ответ

3

Простой пример КВО для наблюдения скрытых:

class SDKViewController : UIViewController { 
    private var context = 0 
    private var observingView: UIView? 

    func initialize(view: UIView) { 
     removeObservations() 

     observingView = view 

     // start observing changes to hidden property of UIView 
     observingView?.addObserver(self, forKeyPath: "hidden", options: [.New], context: &context) 
    } 

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 
     if let newValue = change?[NSKeyValueChangeNewKey] as? Bool where context == &self.context { 
      print("hidden changed: \(newValue)") 
     } 
    } 

    // this is called by deinit 
    // it should also be called if they can deregister the view from your SDK 
    func removeObservations() { 
     if let view = observingView { 
      view.removeObserver(self, forKeyPath: "hidden") 
      observingView = nil 
     } 
    } 

    deinit { 
     removeObservations() 
    } 
} 

Это делает некоторые предположения о конфигурации, но если вы позволяете инициализацию многих взглядов, вы можете легко настроить.

Кроме того, многое из этого более красноречиво, если вы используете KVOController Facebook, который не находится в Swift.

Редактировать: Просто отметить, спрятать Работает с KVO.

Edit # 2: Обновленный YourSDKClass в SDKViewController (NSObject -> UIViewController)

+0

Я взволнован. Это похоже на то, что мне нужно. Тем не менее, я получаю «Значение типа [Контроллер] не имеет« контекста »участника. –

+0

Итак, у меня есть SDKViewController с функцией-членом' initializeInputView', в которой я передаю UIView. Я хочу получать уведомления когда свойство 'hidden' UIView 'изменяется из основного приложения. –

+0

О, и мне нужно будет найти способ обойти тот факт, что класс SDK уже является UIViewController. Добавление NSObject дает мне множественную ошибку наследования. ? –

0

Вы можете использовать Key Value Observing (KVO) для контроля изменений общих свойств классов, который включает в себя свойство hidden на UIView экземплярах. Это делается с использованием addObserver:forKeyPath:options:context:, определенного в протоколе NSKeyValueObserving.

Обратите внимание, что вы также можете скрыть представление, удалив его из своего супервизора или установив alpha на ноль.

+0

UIKit как каркас/модуль не соответствует KVO. Так что это может сработать, а может и нет. Я специально не пытался KVO 'hidden ', но UIKit в целом - это хиты и промахи, когда дело касается KVO. –

+1

@ReidBelton - Я могу подтвердить, что «скрытый» наблюдается, по крайней мере, с IOS 10. Однако, как вы указываете, UIKit не дает никаких гарантий относительно соответствия KVO, поэтому это может потенциально измениться в будущем. –

1

Вот пример с использованием протоколов

protocol MyClassDelegate:class { 
    func myClassValueDidChange(newValue:Int) 
} 

class MyClass { 

    weak var delegate:MyClassDelegate? 
    var value = 0 { 
     didSet { 
      delegate?.myClassValueDidChange(value) 
     } 

    } 
} 


class ViewController:UIViewController,MyClassDelegate { 

    let myClass = MyClass() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     myClass.delegate = self 
    } 

    func myClassValueDidChange(newValue:Int) { 
     //Do something 
    } 


}