I am not if this will work properly
[[cr1.crossRoad.trafficLights
objectForKey: [NSNumber numberWithInt:pedestrianTL]]
addObserver:view
forKeyPath:#"colorState"
options:NSKeyValueObservingOptionNew
context:nil];
The project I'm developing doesn't work properly. This way I was trying to add an observer to change the view with after every change happening to the cell of the colorState array.
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
[self refreshState:object];
}
The program never enters this method though I change values of the colorState cells. Maybe the problem is with me trying to observe array but not actually what it contains?
The problem was that I was trying to observe an array which was not possible that way.
Related
I am working on a MAC application in which I need to get an event that user start resizing column of nstableview. I know there is a notification columnDidResize. But it get called when we ended resizing columns.
Solved the same problem using KVO notifications.
Set your table delegate as an observer for NSTableColumn width:
[column addObserver:self forKeyPath:#"width" options:0 context:nil];
Options argument could be adjusted to get the notification before an actual change takes place.
Then get notified when the width changes:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSInteger resizedColumn = tableView.headerView.resizedColumn;
if (resizedColumn != -1)
{
if (object == column &&
object == [tableView.tableColumns objectAtIndex:resizedColumn])
{
// User is resizing column
}
}
}
Using KVO, as indicated by #pointum works. If you get into troubles related to unregistering the observer, you can do what I actually ended up doing:
Subclass NSTableColumn and override the setter for the Width parameter and send a notification from there.
I have a uiview named subview1. I add this as subview to a couple of other views depending on certain situations. Now I have the following code
[subView1 addObserver:self forKeyPath:#"superview" options:NSKeyValueObservingOptionNew context:nil];
My problem is the obserValueForKeypath function is never called
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if (self.subView1 == (UIView*)object) {
if ([keyPath isEqualToString:#"superview"]) {
NSLog(#"superview changed %#",change);
}
}
}
Am i doing something wrong here.
Just check that if it is going into first if block , the problem might be there.Also check if you have declared property for variable for which you are setting the observer if it is in different class.
I have some code that opens a NSColorPanel. How would I be able to detect when the color is changed and then run a callback?
NSColorPanel *colorPanel = [NSColorPanel sharedColorPanel];
[colorPanel orderFront:nil];
Thanks in advance.
You should use target action:
NSColorPanel *cp = [NSColorPanel sharedColorPanel];
[cp setTarget:self];
[cp setAction:#selector(colorUpdate:)];
and define the action this way:
-(void)colorUpdate:(NSColorPanel*)colorPanel{
NSColor* theColor = colorPanel.color;
....your code
}
There is a method - (void)changeColor:(id)sender. It sends to the first responder when the user selects a color in an NSColorPanel object. You can override this method in any responder that needs to respond to a color change. May be, it can help.
Have you tried using KVO? you can observe the colorPanel from desired controller; in case of change you will get a callback:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
can you help me understand the observeValueForKeyPath method :
here it seems that observeValueForKeyPath is called because we changed the value "for the key : earthquakeList" , but let's say we have another key observed, like "earthquake_New_List",
how can i know that the first, or the second key observed, has changed, if we only have one callback method, the observeValueForKeyPath ?
[self addObserver:self forKeyPath:#"earthquakeList" options:0 context:NULL];
//...
- (void)insertEarthquakes:(NSArray *)earthquakes
{
// this will allow us as an observer to notified (see observeValueForKeyPath)
// so we can update our UITableView
//
[self willChangeValueForKey:#"earthquakeList"];
[self.earthquakeList addObjectsFromArray:earthquakes];
[self didChangeValueForKey:#"earthquakeList"];
}
// listen for changes to the earthquake list coming from our app delegate.
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
[self.tableView reloadData];
}
Thanks
The keyPath parameter in your implementation of observeValueForKeyPath:ofObject:change:context: will tell you which key has changed. So you can do something like:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqualToString:#"key1"]) {
// do something
} else if ([keyPath isEqualToString:#"key2"]) {
// do something else
}
}
The following line sometimes throws SIGABRT:
[[NSUserDefaults standardUserDefaults] synchronize];
I have not idea why it happens.
By the way, the app is multithreaded.
NSUserDefaults is thread safe, that's not the problem. You are over releasing some object in your defaults and synchronize is crashing when it finds it.
This can also happen if you added a Key Value Observer on a preference and did not implement
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context