视图 x 位置的通知
Posted
技术标签:
【中文标题】视图 x 位置的通知【英文标题】:notification for a view x position 【发布时间】:2014-09-03 16:55:24 【问题描述】:在我正在为我的项目开发的幻灯片菜单中,我想在内容视图滑出时添加一个黑色视图。为此,我需要创建一种方法来连续检查视图 x 位置并使黑色层变暗或变亮。此视图的位置与内容视图相同。 我想我可以像这样使用 NSNotificationCenter:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(incomingNotification:) name:@"notification" object: darkViewController.view.frame.origin.x]];
还有一个方法:
- (void) incomingNotification:(NSNotification *)notification
// the dark layer alpha will be 0 at origin=0 and 0.8 at bounds.size.width
float alphaToUse = (darkViewController.view.frame.origin.x / self.view.bounds.size.width) * 0.8;
[darkViewController.view setAlpha:alphaToUse];
问题是我必须使用一个对象作为参数。 我是通知的新手,所以我问:将它们用于这种事情是错误的吗? 用其他方式解决这个问题会更好吗?
编辑: 按照丹尼斯的建议,我现在正在尝试使用键值观察解决方案。 我的应用程序结构如下: MenuViewController-->ContainerViewController-->DarkViewController
在 MenuViewController.m 中:
@interface MenuViewController ()
@property (strong,nonatomic) ContainerViewController *containerViewController;
@property (strong,nonatomic) DarkViewController *darkViewController;
@end
@implementation MenuViewController
@synthesize containerViewController,darkViewController;
# pragma mark - Views
- (void)viewDidLoad
[super viewDidLoad];
containerViewController = [[ContainerViewController alloc]init];
[self addChildViewController:containerViewController];
[self.view addSubview:containerViewController.view];
[containerViewController didMoveToParentViewController:self];
darkViewController = [[DarkViewController alloc]init];
[containerViewController addChildViewController:darkViewController];
[containerViewController.view addSubview:darkViewController.view];
[darkViewController didMoveToParentViewController:containerViewController];
[UIView animateWithDuration:slideDuration delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
[darkViewController.view setAlpha:0.7];
containerViewController.view.frame = CGRectMake(self.view.frame.size.width - slideWidth, 0, self.view.frame.size.width, self.view.frame.size.height);
completion:^(BOOL finished)
if (finished)
];
[darkViewController addObserver:self forKeyPath:@"darkViewController.view.frame.origin.x" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change: (NSDictionary *)change context:(void *)context
NSLog(@"x is changed");
当我运行它时,我得到了这个异常:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<DarkViewController 0x10962d280> addObserver:<MenuViewController 0x10922c890> forKeyPath:@"darkViewController.view.frame.origin.x" options:1 context:0x0] was sent to an object that is not KVC-compliant for the "darkViewController" property.'
好的,我似乎在这个例子Notificationsin ios找到了一个解决方案
我刚刚在 ContainerViewController 的 viewDidLoad 中添加了这个
[self addObserver:self forKeyPath:@"view.frame" options:0 context:nil];
并使用 for 循环实现观察者方法以查找我的 DarkViewController 视图
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
for (UIViewController * vc in self.childViewControllers)
if ([vc isKindOfClass:[DarkViewController class]])
float alphaToUse = (self.view.frame.origin.x / self.view.bounds.size.width) * 0.8;
[vc.view setAlpha:alphaToUse];
现在我只需要了解将 removeObserver 方法放在哪里,因为我的 ContainerViewController 将始终被加载...
【问题讨论】:
【参考方案1】:iOS 中还有另一种机制来处理这种事情,称为键值编码和键值观察。
来自通知中心文档:
在设计应用程序时,不要简单地假设您应该发送通知以与相关方进行沟通。您还应该考虑替代方案,例如键值观察、键值绑定和委托。
在 OS X 10.3 版中引入了键值绑定和键值观察,并提供了一种松散耦合数据的方式。通过键值观察,您可以请求在另一个对象的属性发生更改时得到通知。与常规通知不同,未观察到的更改不会造成性能损失。被观察对象也不需要发布通知,因为键值观察系统可以自动为您做,尽管您仍然可以选择手动做。
因此,如果您在制作幻灯片菜单动画时有另一个通知观察者,则可能会降低其处理性能。
最好的解决方案是调用动画块内的incomingNotification: 方法(动画执行的方法)。
Apple 文档再次:
虽然键值编码很有效,但它增加了一个比直接方法调用稍慢的间接级别。仅当您可以从它提供的灵活性中受益时,您才应该使用键值编码。
回答已编辑的问题:
This answer 准确描述了您正在尝试做的事情。在某些对象的属性上添加观察者时,对象的名称不应包含在属性键路径中。因此,在您的情况下,添加观察者如下所示:
[darkViewController addObserver:self forKeyPath:@"view.frame" options:NSKeyValueObservingOptionNew context:nil];
当尝试观察一些对象属性时,不要忘记确保对象的类对于该属性是 KVC 兼容的!
并且不要忘记在工作完成后移除观察者。
【讨论】:
我阅读并应用了您链接的答案,但它不起作用。 observeValueForKeyPath 方法没有给我任何更新。好吧,我想我必须找到另一个解决方案。我还阅读了文档并检查了几个示例,但老实说,我无法理解这个 KVC-KVO 是如何工作的......无论如何,谢谢你的时间。以上是关于视图 x 位置的通知的主要内容,如果未能解决你的问题,请参考以下文章
不同高度的 UITableViewCells 将其附件视图放置在不同的 X 位置