Is there any way to get the focus value from iPhone camera with autofocus?
I want to use this data to calculate the distance from iPhone to an object in focus.
Obviously this is an old question, but as there is an option to get a "lense value" since iOS8 it should appear here.
Since iOS8 you can get the focus value from the lense by key-value observing lensPosition. It is a property of the AVCaptureDevice class which is part of the AVFoundation framework.
So somewhere in your camera class set the observer:
// Assuming _device is an object of the `AVCaptureDevice` class
[_device addObserver:self forKeyPath:#"lensPosition" options:NSKeyValueObservingOptionNew context:nil];
And in the class you used as observer:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:#"lensPosition"]) {
NSLog(#"change: %#", change);
NSLog(#"lens position: %f", [change[#"new"] floatValue]);
}
}
The position of the lens will be displayed as a scalar value from 0 to 1.
Also you can set the lens position manually. You can find out more about managing the lens position in the Apple Documentation.
Finally as with all key-value observer don't forget to remove the observer.
NOTE: The lens is a mechanical part in the device and focusing is done by moving the lens via a spring. So values differ depending on the device and situation.
I do not think there is such a thing as a focus value.
Related
I have the following problem
during abstraction i have encapsulated a class in objective c which allows me to change a rectangles size and position over an underlying image.
I use this class as in some situations each slightly different.
In one i need to ensure a minimum and maximum size in a other the rect must be a square.
So i observe the value set by the user and check it against rules by using the objective-c methods:
[rectDrawer addObserver:self forKeyPath:#"value" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
In this method i check the constraints. But when i want to correct a invalid value and write it back it comes to that problem with "EXC_BAD_ACCESS" exception
I also tried following to avoid the exception but this does not help
[rectDrawer removeObserver:self forKeyPath:#"value"];
rectDrawer.value = _value;
[rectDrawer addObserver:self forKeyPath:#"value" options:NSKeyValueObservingOptionNew context:nil];
is there a possible solution for this
I'm using AVPlayer to play audio from remote server.
I want to display a progress bar showing the buffering progress and the "time played" progress, like the MPMoviePlayerController does when you play a movie.
Does the AVPlayer has any UI component that display this info? If not, how can I get this info (buffering state)?
Thanks
Does the AVPlayer has any UI component that display this info?
No, there's no UI component for AVPlayer.
If not, how can I get this info (buffering state)?
You should observer AVPlayerItem.loadedTimeRanges
[yourPlayerItem addObserver:self forKeyPath:#"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
then using KVO to watch
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
if(object == player.currentItem && [keyPath isEqualToString:#"loadedTimeRanges"]){
NSArray *timeRanges = (NSArray*)[change objectForKey:NSKeyValueChangeNewKey];
if (timeRanges && [timeRanges count]) {
CMTimeRange timerange=[[timeRanges objectAtIndex:0]CMTimeRangeValue];
}
}
}
timerange.duration is what you expect for.
And you have to draw buffer progress manually.
Refs here.
I would like to be notified about a new insertion in the NSMutableSet and thus this is what I am doing, but for some reason it is not calling observeValueForKeyPath method
Just for test:
-(void)observ{
[self addObserver:self forKeyPath:#"connections" options:NSKeyValueChangeInsertion context:NULL];
[connections addObject:#"connectionName"];
}
This is never called:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if( [keyPath isEqualToString:#"connections"] ) {
NSLog(#"added new object");
}
}
Is NSMutablSet KVC ?
NSMutableSet is indeed KVO/KVC compliant. However, in order to receive the notifications with the way you have this set up, you need to implement the KVC accessor methods for a set. Information can be found here. Essentially, you have to implement methods called:
-countOfConnections
-enumeratorOfConnections
-memberOfConnections:
-addConnectionsObject:
-removeConnectionsObject:
-intersectConnections:
You must use these methods to access and mutate your set in order to receive KVO notifications.
Finally, in your -observeValueForKeyPath method, you can use the value of the key kind in the change dictionary to determine what type of mutation occurred (addition, deletion, etc.). The values can be found here and are listed under "NSKeyValueChange". Hope this helps.
I'm interested in the value change of a particular key which I keep in NSUserdefaults. However, what I have is not working for me. observeValueForKeyPath does not get triggered.
Update: I think I've discovered the issue. Rather than using a defined constant, if I use a string then it gets fired.
[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:kSomethingInteresting options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
NSLog(#"Defaults changed, %#.%#", object, keyPath);
if ((object == [NSUserDefaults standardUserDefaults]) && [keyPath isEqualToString:kSomethingInteresting]) {
NSLog(#"kSomethingInteresting changed in defaults");
}
}
Not ideal but if I precede the addOberver line with:
NSString* keyToObserve = kSomethingInteresting;
And use that in the addObserver line then that works. Seems a bit fiddly?
So I'm going to scrap the use of a defined constant in this instance and in all instances where I need to observe something in userdefaults. Shame, as I like using them for key names throughout.
I'm trying to wrap my head around NSNotification but can't seem to get it to work. Think I'm misunderstanding how to register for an notification.
I have a bool as a property in my connection manager class. At initialisation I authenticate with a few servers and check if I can access an external URL (App will mainly be used on company intranet and an external connection isn't always possible)
The BOOL property will be changed from YES to NO if it cannot access the connection and as this can be responded at any time I thought it would be best to register a notification for when it changes. The property is called externalConnectionAvailable
[ConnectionManager addObserver:self forKeyPath:#"externalConnectionAvailable" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL];
and have the method:
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
NSLog(#"observer called");
}
But this doesn't get called. Am I doing something completely wrong?
Thanks
In this statement:
[ConnectionManager addObserver:self forKeyPath:#"externalConnectionAvailable" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL];
Assuming that you are following the "Cocoa Way" and using the usual naming scheme for classes and object instances, you appear to be trying to add an observer for an entire class, as opposed to an object instance.
You should have something like
ConnectionManager *connectionManagerInstance = // initialize manager...
...
[connectionManagerInstance addObserver:self forKeyPath:#"externalConnectionAvailable" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL];
It was something very stupid. I was just changing the property by calling externalConnectionAvailable not self.externalConnectionAvailable