iOS 7.1 imagePicker CameraFlashMode not indicating ON/OFF state
I have iPhone application which overlays the camera with custom view. I have a button to switch between camera flash mode, this is the code.
self.imagePickerController.cameraFlashMode always displays auto mode.
if ( self.imagePickerController.cameraFlashMode == UIImagePickerControllerCameraFlashModeOn) {
self.imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
[self.flashButton setImage:[UIImage imageNamed:#"flashoff.png"] forState:UIControlStateNormal];
self.flashButton.selected = NO;
}
else
{
self.imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeOn;
[self.flashButton setImage:[UIImage imageNamed:#"flash.png"] forState:UIControlStateNormal];
self.flashButton.selected = YES;
}
NSLog(#"cameraFlashMode: %d",self.imagePickerController.cameraFlashMode);
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInteger:self.imagePickerController.cameraFlashMode] forKey:#"cameraFlashMode"];
When you do:
self.imagePickerController = [[UIImagePickerController alloc] init];
[self.imagePickerController setSourceType:UIImagePickerControllerSourceTypeCamera];
[self.imagePickerController setCameraCaptureMode:UIImagePickerControllerCameraCaptureModePhoto];
//...
(in your particular case) explicitly mention:
[imagePickerController setCameraFlashMode:UIImagePickerControllerCameraFlashModeOn];
If you don't then the camera defaults to UIImagePickerControllerCameraFlashModeAuto
and since the logic you've implemented doesn't handle this case, it remains in UIImagePickerControllerCameraFlashModeAuto
Related
I am using pull to refresh for usual data refresh on a tableview.
Here is my code
-(void)addUIRefreshControl{
//Instantiate and Configure Refresh Control
self.refreshControl = [[UIRefreshControl alloc] init]; // initialize refresh control
self.refreshControl.tintColor = [UIColor appBaseColor]; // set tint color
[self.refreshControl addTarget:self
action:#selector(refreshAPI)
forControlEvents:UIControlEventValueChanged]; // add target
[self.tableView addSubview:self.refreshControl]; // add the refresh control
}
-(void)refreshAPI{
if ([APP_DELEGATE isNetAvailable]) {
[self fetchAPI];
}else{
if (self.refreshControl) {
[self.refreshControl endRefreshing]; //end refreshing
}
}
}
Everything works fine on iOS Devices & Simulator except for iPhone X. Can anyone suggest what am I doing wrong?
Thanks
Is your app iOS 10 & newer only? If so, you should be using your commented out line:
- (void)addUIRefreshControl{
UIRefreshControl * refreshControl = [[UIRefreshControl alloc] init]; // initialize refresh control
refreshControl.tintColor = [UIColor appBaseColor]; // set tint color
refreshControl addTarget:self
action:#selector(refreshAPI)
forControlEvents:UIControlEventValueChanged]; // add target
if (self.tableView != NULL) {
// tableView will have a strong reference (and retain) refreshControl ; no need to have it be its own property
self.tableView.refreshControl = refreshControl
} else {
NSLog(#"suprise! self.tableView is null");
}
}
And you should always call "endRefreshing" when the value changes (or updates). Before, you were calling only if isNetAvailable was false.
-(void)refreshAPI{
if ([APP_DELEGATE isNetAvailable]) {
[self fetchAPI];
}
[self.tableView.refreshControl endRefreshing]; //end refreshing
}
Migrating to AVkit from MPMoviePlayer has brought me to a blocking issue.
I need to display a custom tableView over the AVPlayerViewController.
I can this tableview trough
[self.avVideoPlayer.contentOverlayView addsubiew:self.mycustomTableView]
and it is visible but it doesn't receive any tap/swipe events.
Any ideas why this happens or how can I add the table view in a place where it would receive the touch events even in the fullscreen mode?
[self.view addSubview:btn];
This will add the button in the minimised player.
Now for the fullscreen scenario you need to add an observer for the videoBounds, here is my code:
[self.avVideoPlayer addObserver:self forKeyPath:#"videoBounds" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
Now here comes the not so pretty part:
- (void)observeValueForKeyPath: (NSString*) path
ofObject: (id)object
change: (NSDictionary*)change
context: (void*)context {
NSLog(#"SOME OBSERVER DID THIS: %# , %#",object,change);
if ([self playerIsFullscreen]) {
for(UIWindow* tempWindow in [[UIApplication sharedApplication]windows]){
for(UIView* tempView in [tempWindow subviews]){
if ([[tempView description] rangeOfString:#"UIInputSetContainerView"].location != NSNotFound){
UIButton *testB = [[UIButton alloc] initWithFrame: CGRectMake(20, 20, 400, 400)];
testB.backgroundColor = [UIColor redColor];
[testB addTarget:self action:#selector(buttonTouch) forControlEvents:UIControlEventTouchDown];
[tempView addSubview:testB];
break;
}
}
}
}
}
I know this is a not a nice way to do it, but it is the only way I managed to add some custom UI that also receives touch events on the player.
Cheers!
I am making app like Instagram .i am using GPUImage framework ,in this i have to take photos and videos and share. i able to capture photos using this framework and now i have to capture video but i am struggling how to change camera mode photos to video. any help and tutorial then its very good for me. I used this code camera for photos mode.
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
self.imagepicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[[NSBundle mainBundle] loadNibNamed:#"OverlayView" owner:self options:nil];
self.overlayView.frame = self.imagepicker.cameraOverlayView.frame;
self.imagepicker.cameraOverlayView = self.overlayView;
self.overlayView = nil;
CGSize result = [[UIScreen mainScreen] bounds].size;
self.imagepicker.showsCameraControls = NO;
self.imagepicker.allowsEditing = NO;
self.imagepicker.wantsFullScreenLayout = NO;
// self.imagepicker.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
}
else{
self.imagepicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
In my case, I'm using GPUImage to do both (pictures and videos). Therefore I've created two objects: one of type GPUImageStillCamera(pictures) and other of type GPUImageVideoCamera (videos).
So whenever you need to switch between cameras you basically stop the GPUImageStillCamera capture and initialize a video camera (note that you have to adapt this snippet to your project):
func initializeVideoCamera() {
// Stop the capture of GPUImageStillCamera
stillCamera.stopCameraCapture()
videoCamera = GPUImageVideoCamera.init(sessionPreset: AVCaptureSessionPreset1920x1080, cameraPosition: .Back)
videoCamera?.outputImageOrientation = .Portrait
videoCamera?.addTarget(filter)
// If a file already exists, AVAssetWriter won't let you record new frames, so delete the old movie
unlink(pathToMovieFile)
initializeWriteWithPath(pathToMovieFile)
videoCamera?.startCameraCapture()
}
I am using an applicationMusicPlayer and when i try to change the volume appear the visual notification, as shown in the picture.
Here the code I am using:
[MPMusicPlayerController applicationMusicPlayer] setVolume:newVolune];
Anyone knows how to hide this notification?
I don't know where the docs says so, but if you add a MPVolumeView view to your app the system volume overlay goes away. Even if it is not visible:
- (void) viewDidLoad
{
[super viewDidLoad];
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame: CGRectZero];
[self.view addSubview: volumeView];
[volumeView release];
...
}
You can use the hardware volume buttons, the setVolume method or directly interact with the control (if visible) that the overlay doesn't show up.
For iOS6 I had to set an image with alpha 0 and non-zero size to the MPVolumeView's image fields in order to get the default volume change notification to disappear.
// hide the hardware volume slider
UIImage *thumb = [[UIImage alloc] initWithCIImage:[UIImage imageNamed:#"volumeHider"].CIImage scale:0.0 orientation:UIImageOrientationUp];
MPVolumeView *hwVolume = [[MPVolumeView alloc] initWithFrame:self.frame];
[hwVolume setUserInteractionEnabled:NO];
hwVolume.showsRouteButton = NO;
[hwVolume setVolumeThumbImage:thumb forState:UIControlStateNormal];
[hwVolume setMinimumVolumeSliderImage:thumb forState:UIControlStateNormal];
[hwVolume setMaximumVolumeSliderImage:thumb forState:UIControlStateNormal];
[self addSubview:hwVolume];
This made the MPVolumeView be "visible" on the screen, but invisible to the user.
I encountered the same issue recently. Instead of adding the MPVolumeView to current view controller's view, I add it to the application's window once at the start of the app:
CGRect rect = CGRectMake(-500, -500, 0, 0);
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:rect];
[self.window addSubview:volumeView];
This works in both iOS 7 and 8.
Swift 3
You can hide the System MPVolumeView using
override func viewDidLoad() {
super.viewDidLoad()
let volumeView = MPVolumeView(frame: CGRect.zero)
self.view.addSubview(volumeView)
}
I had success with this in iOS 6. Although it wouldn't perform well. It caused quite a bit of lag when sliding the thumbImage. I did have to take out the last 2 lines of code in order for this to work.
[volumeView release];
...
For me, on iOS 7, none of above solutions worked. Here is how I did it:
_volume = [[MPVolumeView alloc] initWithFrame: CGRectMake(-100,-100,16,16)];
_volume.showsRouteButton = NO;
_volume.userInteractionEnabled = NO;
[self.view addSubview:_volume];
[_volume release];
That is, simply set MPVolumeView's frame to an off-screen location such as (-100,-100).
In order to make my custom UIImagePickerSourceTypeCamera, I had to do this:
pickerOne = [[UIImagePickerController alloc] init];
pickerOne.delegate = self;
pickerOne.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerOne.showsCameraControls = NO;
pickerOne.navigationBarHidden = YES;
pickerOne.toolbarHidden = YES;
pickerOne.wantsFullScreenLayout = YES;
But now, when I take a picture like this:
[cameraButton addTarget:pickerOne
action:#selector(takePicture)
forControlEvents:UIControlEventTouchUpInside];
it doesn't show the shutter when you take the picture. Is there a way to show it programmatically?
It is possible. The trick is to do the following:
Enable the camera controls on initializing the picker (this will enable the shutter view).
pickerOne.showsCameraControls = YES;
Overlay the camera controls with your own view which has the cameraButton
In your takePicture: method do the following:
pickerOne.showsCameraControls = NO;
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.0]];
[pickerOne takePicture];
In the imagePickerController:didFinishPickingMediaWithInfo: method do the following:
pickerOne.showsCameraControls = YES; // perform on main thread
There is no way to control the "shutter" affect. You can however create your own image and add the affect in there.