2016-02-01 12 views
5

Ho creato un XIB personalizzato che si estende da UITableViewHeaderFooterView e si tenta di aggiungere un riconoscitore di gesti. L'unico problema sta tentando di aggiungere il sistema di riconoscimento tramite i risultati Interface Builder nell'oggetto che viene aggiunto alla gerarchia di livello superiore e il seguente errore che causa il mio app di crash:Aggiunta di UITapGestureRecognizer a XIB

terminazione app a causa di eccezione non identificata 'NSInternalInconsistencyException', la ragione: 'pennino non valido registrato per identificatore (AccordionHeader) - pennino deve contenere esattamente un oggetto di livello superiore che deve essere un esempio UITableViewHeaderFooterView'

al meglio della mia conoscenza non c'è "viewDidLoad" equivalente disponibile o mi sarebbe solo l'aggiunta di il riconoscimento a livello di codice c'è un altro modo per fare ciò?

risposta

0

Hai ragione, il riconoscimento non deve essere aggiunto all'XIB al livello superiore.

La mia soluzione come segue:

class SettingsUserAvatarHeader: UITableViewHeaderFooterView { 

    // Set as a variable, as it will be re-created on cell re-use 
    var tapGestureRecognizer = UITapGestureRecognizer() 

    // This will be called every time the cell moves off screen and returns 
    override func prepareForReuse() { 
     super.prepareForReuse() 

     // Needs to be done manually. 
     tapGestureRecognizer = UITapGestureRecognizer() 
     avatarImageView.gestureRecognizers = [ tapGestureRecognizer ] 
    } 

    // This will be needed for the first display 
    override func didMoveToSuperview() { 
     super.didMoveToSuperview() 

     avatarImageView.gestureRecognizers = [ tapGestureRecognizer ] 
    } 
} 

Con questo, è possibile ascoltare i rubinetti direttamente. Sto utilizzando RxSwift:

In primo luogo, aggiungere un estensione per il rubinetto:

extension Reactive where Base: SettingsUserAvatarHeader { 

    var avatarTap: ControlEvent<UITapGestureRecognizer> { 
     return self.base.tapGestureRecognizer.rx.event.asControlEvent() 
    } 

} 

E nel controller/Delegato etc:

class Consumer: UITableViewDelegate { 

    var avatarTapDisposable: Disposable? 

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
     let cell = tableView.dequeueReusableHeaderFooterView(withIdentifier: "userAvatarView") 
     let view = cell as! SettingsUserAvatarHeader 

     avatarTapDisposable = 
       view.rx 
        .avatarTap 
        .subscribe(onNext: { (tap) in 
         // Here your code for the tap 
        }) 

     return cell 
    } 
}