Correct way to set camera exposure point in iOS - iphone

I am trying to set the camera exposure points in iOS 5 (iPhone 4s test device):
if ([_videoDevice lockForConfiguration:nil])
{
if ([_videoDevice isExposurePointOfInterestSupported])
{
[_videoDevice setExposurePointOfInterest:CGPointMake(0.2,0.2)];
if ([_videoDevice isExposureModeSupported:AVCaptureExposureModeAutoExpose])
{
[_videoDevice setExposureMode:AVCaptureExposureModeAutoExpose];
NSLog(#"Adjusting exposure: %d", [_videoDevice isAdjustingExposure]);
}
}
[_videoDevice unlockForConfiguration];
}
According to the documentation "AVCaptureExposureModeAutoExpose" should set the exposure and then lock. My problem is that "isAdjustingExposure" always returns false. I even tried to set some sleeps but it remains at false state.
How can I correctly set the exposure point?
Regards,

The trick is to set "AVCaptureExposureModeContinuousAutoExposure" and use key/value observing.

Related

SCNCamera.exposureOffset not working in iOS13

SCNCamera.wantsHDR is true. Yet any changes to SCNCamera.exposureOffset are not visible on iOS13 devices. But it is working perfectly fine on iOS12.
if let camera = self.sceneView.pointOfView?.camera {
camera.exposureOffset = -5
}
You said absolutely right, if someone wanna use exposureOffset instance property in SceneKit, he/she needs to activate a wantsHDR property at first:
var wantsHDR: Bool { get set }
In real code it might look like this:
sceneView.pointOfView!.camera!.wantsHDR = true
sceneView.pointOfView!.camera!.exposureOffset = -5
But there's a bug in iOS 13 and iOS 13 Simulator. However, if you disable allowsCameraControl, exposureOffset works fine.
sceneView.allowsCameraControl = false
Here's how exposureOffset changes from -2 to 2:

SKAction scaleTo not working on iPhone 5S

I've found a strange behavior while using the iPhone 5S as development-target(Simulator and real device).
I'd like to scale a SKSpriteNode with an SKAction.scaleTo. This works fine on the iPhone 4S and the iPhone 5 simulator(Tested with iOS 7.0.3 and iOS 8).
But on the iPhone 5S simulator, the node doesn't scale. Also on my real iPhone 5S it doesn't scale.
Here is my code:
for tile in tileArray{
if(tile.color == searchColor){
var action = SKAction.scaleTo(0.5, duration: 0.5)
var action2 = SKAction.scaleTo(1, duration: 0.5)
tile.runAction(SKAction.repeatActionForever(SKAction.sequence([action, action2])))
}
}
EDIT:I've now found out, that the if-block doesn't get called on the iPhone 5S. I don't know why. For the other iPhones it works.
But as you see, the two colors are the same:
UIDeviceRGBColorSpace 0.203922 0.286275 0.368627 1
UIDeviceRGBColorSpace 0.203922 0.286275 0.368627 1
How is that possible?
Important: Other SKaction.scaleTo actions are working without any problems.
You are not comparing colors, you are comparing pointer values:
if(tile.color == searchColor)
This tests whether tile.color and searchColor both point to the same memory address. Depending on how the color is created, these addresses may be different. Try testing the individual color components as in:
if (tile.color.r == seachColor.r && tile.color.g == searchColor.b && etc ..)
Note that equality for floating point values is "relative".
The cause is the UIDeviceRGBColorSpace, which is different on the iPhone 5S. So I had to create an object-class which has also a name in it. Now I have to add the colornames to the class too, but I can compare the colors that way:
var color1 = ColorClass("myRed", color:theColor)
var color2 = ColorClass("myRed", color:theColor2)
if(color1.name == color2.name){
}
Of course this fix is really case-dependant. So for many others, this solution won't be good enough for their purposes.

Navigation based on screen orientation (landscape or portrait) in Flash CS6

I'm creating an app that will have a different menu if the phone is held landscape, or portrait.
I figure I have to tell flash to move to a new frame when the phone moves from landscape to portrait or vice versa, but I'm not sure the exact code to after creating the orientation event listener.
There are two ways. Listen for a StageOrientationEvent or listen for Event.RESIZE. I personally prefer to use RESIZE as it is called slightly more often and keeps your interface in sync more.
var landscapeNav:Sprite; // this would be your landscape nav. Obviously does not have to be a Sprite
var portraitNav:Sprite; // same as landscapeNav, but this represents your portrait nav
stage.addEventListener( Event.RESIZE, this.stageResizeHandler );
function stageResizeHandler( e:Event ):void {
if ( stage ) { //just to make sure the stage is loaded in this class so we avoid null refs
if ( stage.stageWidth >= stage.stageHeight ) {
landscapeNav.visible = true;
portraitNav.visible = false;
}
else {
landscapeNav.visible = false;
portraitNav.visible = true;
}
}
}
This could definitely be cleaned up (landscapeNav.visible = stage.stageWidth > stage.stageHeight) but this should give you something to go on. If you want to do an animation as Atriace suggested, you would do a TweenLite/Max call within the conditional in the function instead of setting visible to true/false (after the animation is done, though, you should set visible to false just for the same of optimzation)
You don't need to create a new frame. In fact, it may be more visually appealing to watch the old menu slide off, and the new one to animate in (like with TweenLite).
The documentation on orientation change can be found # Adobe's ActionScript APIs specific to mobile AIR applications: "Screen Orientation", and the API.

jump into "audioPlayerDidFinishPlaying" function unexpected

I used an AVAudioPlayer object to control playing multiple music files. I also created an UISlider to control seeking file. But i have a problem when seek the pointer. After seeking, AVAudioPlayer update time correct then jump into "audioPlayerDidFinishPlaying" function unexpected.
Here is the code that i used :
-(void)timeChange
{
_player.currentTime = _timeControl.value;
[self updateCurrentTimeForPlayer];
}
-(void)updateCurrentTimeForPlayer
{
if(_isNeedUpdate == NO) return;
_timeControl.maximumValue = _player.duration;
}
A long shot, but maybe the audio format doesn't support seeking?
Why the call to updateCurrentTimeForPlayer? Where is _isNeedUpdate set? (Why all the underscores?)
Can you add some debug NSLogs to find out what's going on?

how to run vibrate continuously in iphone?

In my application I'm using following coding pattern to vibrate my iPhone device
Include: AudioToolbox framework
Header File:
#import "AudioToolbox/AudioServices.h"
Code:
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
My problem is that when I run my application it gets vibrate but only for second but I want that it will vibrate continuously until I will stop it.
How could it be possible?
Thankfully, it's not possible to change the duration of the vibration. The only way to trigger the vibration is to play the kSystemSoundID_Vibrate as you have. If you really want to though, what you can do is to repeat the vibration indefinitely, resulting in a pulsing vibration effect instead of a long continuous one. To do this, you need to register a callback function that will get called when the vibration sound that you play is complete:
AudioServicesAddSystemSoundCompletion (
kSystemSoundID_Vibrate,
NULL,
NULL,
MyAudioServicesSystemSoundCompletionProc,
NULL
);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Then you define your callback function to replay the vibrate sound again:
#pragma mark AudioService callback function prototypes
void MyAudioServicesSystemSoundCompletionProc (
SystemSoundID ssID,
void *clientData
);
#pragma mark AudioService callback function implementation
// Callback that gets called after we finish buzzing, so we
// can buzz a second time.
void MyAudioServicesSystemSoundCompletionProc (
SystemSoundID ssID,
void *clientData
) {
if (iShouldKeepBuzzing) { // Your logic here...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
} else {
//Unregister, so we don't get called again...
AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
}
}
There are numerous examples that show how to do this with a private CoreTelephony call: _CTServerConnectionSetVibratorState, but it's really not a sensible course of action since your app will get rejected for abusing the vibrate feature like that. Just don't do it.
Read the Apple Human Interaction Guidelines for iPhone. I believe this is not approved behavior in an app.
iOS 5 has implemented Custom Vibrations mode. So in some cases variable vibration is acceptable. The only thing is unknown what library deals with that (pretty sure not CoreTelephony) and if it is open for developers. So keep on searching.
The above answers are good and you can do it in a simple way also.
You can use the recursive method calls.
func vibrateTheDeviceContinuously() throws {
// Added concurrent queue for next & Vibrate device
DispatchQueue.global(qos: .utility).async {
//Vibrate the device
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
self.incrementalCount += 1
usleep(800000) // if you don't want pause in between, remove this line.
do {
if let isKeepBuzzing = self.iShouldKeepBuzzing , isKeepBuzzing == true {
try self.vibrateTheDeviceContinuously()
}
else {
return
}
} catch {
//Exception handle
print("exception")
}
}
}
To stop the device vibration use the following line.
self.iShouldKeepBuzzing = false
ios swift