Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS: Adding observer to a UIView's frame.origin.y?

Tags:

ios

frame

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 ?

like image 740
Sethypie Avatar asked Jul 31 '13 16:07

Sethypie


3 Answers

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];
like image 170
Sethypie Avatar answered Nov 05 '22 06:11

Sethypie


With ReactiveCocoa is as simple as:

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

for example.

like image 5
thelastinuit Avatar answered Nov 05 '22 06:11

thelastinuit


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
    }
 }
like image 2
Istvan Avatar answered Nov 05 '22 07:11

Istvan