当绝对坐标中的帧变化时如何通知?

时间:2014-11-30 18:54:35

标签: ios objective-c uiview frame

我需要在我的自定义UIView子类的绝对帧时得到通知(不仅相对于其父级的帧,而且当superview&#s; / grandsuperview' s等帧发生变化时,我的视图和#39;要更改的帧)屏幕上的更改。我尝试在convertRect:toView:-(void)didMoveToSuperview获取绝对帧-(void)didMoveToWindow,并且我还在这两个内添加了此代码:

UIView *view = self.superview;
while (view) {
    [view addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
    [view addObserver:self forKeyPath:@"superview" options:NSKeyValueObservingOptionNew context:nil];
    view = view.superview;
}

它们都被称为几次(这没关系),但我得到的坐标不正确。在所有设置实际可见帧的代码后,运行其他东西。我通过将其放入我的代码来验证这一点:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        CGRect globalFrame = [view.superview.superview convertRect:view.superview.frame toView:[[view.delegate tutorialView] superview]];
        NSLog(@"after 2 sec %@", NSStringFromCGRect(globalFrame));
        if([view.delegate respondsToSelector:@selector(attachedViewFrameDidChange:)]){
            [view.delegate attachedViewFrameDidChange:globalFrame];
        }
    });

忘记view.delegate和我的其他自定义参数/对象/方法。两秒钟后,我在globalFrame中获得了正确的值。我在-(void)didMoveToSuperview-(void)didMoveToWindow-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context中使用完全相同的代码,并且调用错误的帧值(在调用convertRect:toView:时获取的值不正确。)为什么这样是的,我怎样才能得到绝对/真实的帧值(我在屏幕上看到的那个),因为我在两秒后得到了,显然没有等待?

1 个答案:

答案 0 :(得分:1)

我认为您可以通过使自定义视图成为视图控制器的委托,并在viewDidLayoutSubviews中调用委托方法来实现此目的。所以,在视图controller.h中,我有了这个,

@protocol UIViewControllerLayoutChanged <NSObject>
-(void)layoutChanged;
@end

@interface ViewController : UIViewController
@property (weak,nonatomic) id<UIViewControllerLayoutChanged> delegate;
@end

在.m文件中,

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setDelegate:(RDLabel *)self.label]; // self.label is the view I want to be notified when its absolute frame changes
}


-(void)viewDidLayoutSubviews {
     [self.delegate layoutChanged];
}

在我的自定义视图类中,

-(void)layoutChanged {
    NSLog(@"%@",NSStringFromCGRect([self.superview convertRect:self.frame toView:nil]));
}

每当我改变它时,这给了我正确的绝对帧。当然,每当任何视图需要重新布局时,即使它不涉及您关注的视图,也会调用viewDidLayoutSubviews。要处理这个问题,您可能需要在自定义类的代码中保留对框架的引用,并且只有在框架从旧值更改时才需要执行任何操作。