iOS: Adding observer to a UIView's frame.origi

2020-07-05 10:56发布

I'm trying to monitor and react to the changing value of the origin of a UIView's frame. My code:

[cell.bottomView addObserver:self forKeyPath:@"frame.origin" options:NSKeyValueObservingOptionNew context:NULL];

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"%@ Changed", keyPath);
}

I'm getting the following error message that I don't understand:

An instance 0x7587d10 of class NSConcreteValue was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0x7587fd0> (
<NSKeyValueObservance 0x7587f70: Observer: 0x7587bd0, Key path: origin, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x7587ff0>
)

Really, I'm only interested in the y position of the origin but the code won't even compile if I set the keyPath to "frame.origin.y".

If I set the keyPath to simply "frame", there are no errors but the method observeValueForKeyPath never gets called. I guess a change to a frame's origin doesn't count as a change to the frame..?

How do I accomplish adding an observer to a UIView's frame.origin.y ?

标签: ios frame
3条回答
做自己的国王
2楼-- · 2020-07-05 11:32

Although I could not solve my problem exactly in the way that I initially wanted, I have found out that I am able to add observers correctly to the UIView's center. By monitoring the center of my view I can determine that the frame's origin has changed.

[cell.bottomView addObserver:self forKeyPath:@"center" options:NSKeyValueObservingOptionNew context:NULL];
查看更多
劫难
3楼-- · 2020-07-05 11:33

I don't think it is possible observe only the y value of the frame. But instead of observing the frame property you could overwrite the setFrame: method

Like this:

- (void)setFrame:(CGRect)frame 
{
    [super setFrame:frame]
    if (self.frame.origin.y != frame.origin.y){
         // Do your stuff here
    }
 }
查看更多
对你真心纯属浪费
4楼-- · 2020-07-05 11:49

With ReactiveCocoa is as simple as:

[RACObserve(self.view, frame) subscribeNext:^(NSNumber *rect) {
        NSLog(@"position y: %f", rect.CGRectValue.origin.y);
    }];

for example.

查看更多
登录 后发表回答