Je veux regarder en UIView
s' frame
, bounds
ou center
de la propriété. Comment puis-je utiliser la Clé-Valeur d'Observation pour y parvenir?
Réponses
Trop de publicités?Il y a généralement des notifications ou d'autres événements observables où KVO n'est pas pris en charge. Même si les docs dit "non", il est apparemment en sécurité à observer les CALayer la sauvegarde de la UIView. L'observation de la CALayer fonctionne dans la pratique en raison de son utilisation intensive de KVO et bon accesseurs (au lieu de ivar de manipulation). Il n'est pas garanti pour fonctionner à l'avenir.
De toute façon, le point de vue de l'image est juste le produit d'autres propriétés. Donc nous avons besoin d'observer ces
[view addObserver:self forKeyPath:@"frame" options:0 context:NULL];
[view.layer addObserver:self forKeyPath:@"bounds" options:0 context:NULL];
[view.layer addObserver:self forKeyPath:@"transform" options:0 context:NULL];
[view.layer addObserver:self forKeyPath:@"position" options:0 context:NULL];
[view.layer addObserver:self forKeyPath:@"zPosition" options:0 context:NULL];
[view.layer addObserver:self forKeyPath:@"anchorPoint" options:0 context:NULL];
[view.layer addObserver:self forKeyPath:@"anchorPointZ" options:0 context:NULL];
[view.layer addObserver:self forKeyPath:@"frame" options:0 context:NULL];
[view.layer addObserver:self forKeyPath:@"transform" options:0 context:NULL];
Voir l'exemple complet ici https://gist.github.com/hfossli/7234623
REMARQUE: Ce n'est pas dit pour être pris en charge dans les docs, mais il fonctionne aujourd'hui avec toutes les versions d'iOS à ce jour (actuellement iOS 2 -> iOS 8 GM)
EDIT: je ne pense pas que cette solution est assez approfondie. Cette réponse est gardé pour des raisons historiques. Voir mon nouveau réponse ici: http://stackoverflow.com/a/19687115/202451
Vous avez à faire, KVO sur le cadre-de la propriété. "auto" est dans ce cas un UIViewController.
l'ajout de l'observateur (généralement dans viewDidLoad):
[self addObserver:self forKeyPath:@"view.frame" options:NSKeyValueObservingOptionOld context:NULL];
retrait de l'observateur (généralement dans dealloc ou viewDidDisappear:):
[self removeObserver:self forKeyPath:@"view.frame"];
Obtention d'informations sur le changement
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if([keyPath isEqualToString:@"view.frame"]) {
CGRect oldFrame = CGRectNull;
CGRect newFrame = CGRectNull;
if([change objectForKey:@"old"] != [NSNull null]) {
oldFrame = [[change objectForKey:@"old"] CGRectValue];
}
if([object valueForKeyPath:keyPath] != [NSNull null]) {
newFrame = [[object valueForKeyPath:keyPath] CGRectValue];
}
}
}
Actuellement, il n'est pas possible d'utiliser KVO d'observer une vue de l'image. Propriétés doivent être KVO conformes à être observables. Malheureusement, les propriétés de la UIKit cadre sont généralement pas observables, comme avec tout autre système de cadre.
À partir de la documentation:
Remarque: Bien que les classes du framework UIKit ne supportent généralement pas KVO, vous pouvez toujours le mettre en œuvre dans les objets personnalisés de votre application, y compris les vues personnalisées.
Il y a quelques exceptions à cette règle, comme NSOperationQueue de l' operations
de la propriété, mais ils doivent être explicitement décrite.
Même si l'aide de KVO sur une vue des propriétés pourraient actuellement le travail je ne recommande pas de l'utiliser dans le code de la navigation. C'est un fragile approche et s'appuie sur les sans-papiers comportement.
Si je peux contribuer à la conversation: comme d'autres l'ont souligné, frame
n'est pas garantie à clé-valeur de l'observable lui-même et ne sont ni l' CALayer
propriétés, même si elles semblent être.
Ce que vous pouvez faire à la place est de créer un personnalisé, UIView
sous-classe qui remplace setFrame:
, et annonce que la réception d'un délégué. Définir l' autoresizingMask
, de sorte que le point de vue a flexible tout. Le configurer pour être totalement transparent et de petite taille (pour économiser des coûts sur l' CALayer
sauvegarde, non pas que cela importe beaucoup) et de l'ajouter en tant que sous-vue de la vue que vous souhaitez regarder les changements de taille.
Cela a fonctionné avec succès pour moi le chemin du retour sous iOS 4 lorsque nous avons été les premiers en précisant iOS 5 comme l'API de code et, par conséquent, besoin temporaire d'émulation de l' viewDidLayoutSubviews
(bien que primordial layoutSubviews
a été plus approprié, mais vous obtenez le point).
Il n'est pas sûr d'utiliser KVO dans certains UIKit les propriétés comme l' frame
. Ou du moins c'est ce qu'Apple a dit.
Je vous conseille d'utiliser ReactiveCocoa, cela vous aidera à écouter des changements dans toute la propriété, sans l'aide de KVO, il est très facile de commencer à observer quelque chose à l'aide de Signaux:
[RACObserve(self, frame) subscribeNext:^(CGRect frame) {
//do whatever you want with the new frame
}];