I have a button on my custom camera overlay that invokes this method:
- (void) changeFlash:(id)sender
{
//UIImagePickerControllerCameraFlashModeOff = -1,
//UIImagePickerControllerCameraFlashModeAuto = 0,
//UIImagePickerControllerCameraFlashModeOn = 1
NSLog(#"before %d", self.picker.cameraFlashMode);
switch (self.picker.cameraFlashMode) {
case UIImagePickerControllerCameraFlashModeAuto:
[(UIButton *)sender setImage:[UIImage imageNamed:#"flashOn"] forState:UIControlStateNormal];
self.picker.cameraFlashMode = UIImagePickerControllerCameraFlashModeOn;
break;
case UIImagePickerControllerCameraFlashModeOn:
[(UIButton *)sender setImage:[UIImage imageNamed:#"flashOff"] forState:UIControlStateNormal];
self.picker.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
break;
case UIImagePickerControllerCameraFlashModeOff:
[(UIButton *)sender setImage:[UIImage imageNamed:#"flashAuto"] forState:UIControlStateNormal];
self.picker.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
break;
}
NSLog(#"after %d", self.picker.cameraFlashMode);
}
self.picker.cameraFlashMode is always 0, before and after changing it. What am I doing wrong?
Also, the flash never works, even though it's supposedly stuck in UIImagePickerControllerCameraFlashModeAuto.
self.picker is nil. This is a common mistake, and you need to check this often, because, unlike Java and other languages, it's valid to send a message to nil in Objective-C.
Related
I have just successfully set up somewhat of a music player. It queries the user's iTunes and plays songs based on the query. For some reason, the button, won't change when the Playback state changes. I have both and NSLog and Label and they both reference it but when it comes to the button, nothing happens. Here's the code:
- (void) handle_PlaybackStateChanged: (id) notification {
MPMusicPlaybackState playbackState = [self.player playbackState];
if (playbackState == MPMusicPlaybackStatePaused) {
self.textLabel.text = #"play";
[PlayButton setTitle:#"STOP" forState:UIControlStateNormal]; // To set the title
NSLog (#"This is paused");
self.playBarButton.title = #"Play";
self.PlayButton = PlayButton;
[self.PlayButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
} else if (playbackState == MPMusicPlaybackStatePlaying) {
self.textLabel.text = #"pause";
[PlayButton setTitle:#"Pause" forState:UIControlStateNormal];
self.PlayButton = PauseButton;
NSLog (#"This is playing");
} else if (playbackState == MPMusicPlaybackStateStopped) {
self.textLabel.text = #"Play";
self.PlayButton = PlayButton;
[self.player stop];
}
}
Any ideas?
I figured this out. I just needed to add the code below in viewDidLoad
if ([musicPlayer playbackState] == MPMusicPlaybackStatePlaying) {
[playPauseButton setImage:[UIImage imageNamed:#"pauseButton.png"] forState:UIControlStateNormal];
} else {
[playPauseButton setImage:[UIImage imageNamed:#"playButton.png"] forState:UIControlStateNormal];
}
I have n number of buttons in the scrollView. If click on a button its text color is changing but if I click another button the text color of the previous button remain unchanged. I want to change the previous button text color as default color while clicking another button. The behavior will be just like a segmented control. Please help me regarding this, I've providing my code below:
-(void) loadScrollView:(CGRect)scrollViewFrame withButtonArray:(NSArray*)buttonArray withCase: (int)ButtonCase
{
scrollView=[[UIScrollView alloc]initWithFrame:scrollViewFrame];
[scrollView setScrollEnabled:YES];
[scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setContentSize:CGSizeMake(100 * 768, 40)];
for (int i = 0; i < [buttonArray count]; i++)
{
adButtonOutLet = [[UIButton alloc] initWithFrame:CGRectMake(140*i, 0, 135, 40)];
if (ButtonCase==0) {
[adButtonOutLet setBackgroundColor:UIColorFromRGB(0X272c2f)];
[adButtonOutLet setTitleColor:UIColorFromRGB(0x969696) forState:UIControlStateNormal];
}
else
{
if (i==0) {
adButtonOutLet.backgroundColor=UIColorFromRGB(0x000000) ;
[adButtonOutLet setTitleColor:UIColorFromRGB(0x179d95) forState:UIControlStateNormal];
}
}
adButtonOutLet.titleLabel.font=[UIFont fontWithName:#"MyriadPro" size:14.0];
[adButtonOutLet setTitle:[buttonArray objectAtIndex:i] forState:UIControlStateNormal];
adButtonOutLet.userInteractionEnabled= YES;
[adButtonOutLet setTag:i];
[adButtonOutLet addTarget:self action:#selector(adButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:adButtonOutLet];
[self.view addSubview:scrollView];
}
}
Here is my action method:
-(void)adButtonAction:(UIButton*)sender
{
for (int i = 0; i < [menuArray count]; i++)
{
int prevTag = 0;
if (sender.tag == i && Case==0)
{
[self reloadScrollViewwithButtonTag:i];
// [sender setSelected:YES];
sender.backgroundColor=UIColorFromRGB(0x000000) ;
[sender setTitleColor:UIColorFromRGB(0x179d95) forState:UIControlStateNormal];
prevTag=i;
}
if (Case==1) {
sender.backgroundColor=UIColorFromRGB(0x000000) ;
[sender setTitleColor:UIColorFromRGB(0x179d95) forState:UIControlStateNormal];
if (sender.tag==prevTag-1) {
[sender setBackgroundColor:UIColorFromRGB(0X272c2f)];
[sender setTitleColor:UIColorFromRGB(0x969696) forState:UIControlStateNormal];
}
}
}
}
Why don't you try changing all buttons style to no selected except the one that is on the sender parameter (selected button)?
-(void)adButtonAction:(UIButton*)sender{
for (int i = 0; i < [menuArray count]; i++)
{
if (sender == menuArray[i])
{
//Selected code style
}
else{
//No selected code style
}
}
}
Considering menuArray is an array with all buttons.
This way you check and modify all styles when a button is pressed.
Hope this could help you or at last give you a clue for resolve your problem.
I don' understand everything in your adButtonAction (what is menuArray?) method but I think what you need is simple, just adapt it to your method.
First create a NSMutableArray to keep reference on your button list:
for (int i = 0; i < [buttonArray count]; i++)
{
adButtonOutLet = [[UIButton alloc] initWithFrame:CGRectMake(140*i, 0, 135, 40)];
[myButtonArray addObject:adButtonOutlet];
....
Then in you action method, set the right color:
for (UIButton* b in myButtonArray){
if(b.tag == sender.tag){
[self setSelectedColor:YES forButton:b];
// Do what you want here
}
else{
[self setSelectedColor:NO forButton:b];
}
}
With:
-(void)setSelectedColor:(BOOL)selected forButton:(UIButton)button{
if(selected){
sender.backgroundColor=UIColorFromRGB(0x000000) ;
[sender setTitleColor:UIColorFromRGB(0x179d95) forState:UIControlStateNormal];
}
else{
[sender setBackgroundColor:UIColorFromRGB(0X272c2f)];
[sender setTitleColor:UIColorFromRGB(0x969696)forState:UIControlStateNormal];
}
}
Apply state vise( Normal,Selected ) title color of button.
Just persist a selected button reference as weak.
while user clicked on button set that button state as selected instead normal.
Change last selected button state Normal instead Selected.
Check out below code that will be help you
UIButton *selectedButton;
-(void)adButtonAction:(UIButton*)sender
{
UIButton *tempButton = sender;
if (selectedButton && selectedButton!=tempButton)
{
[selectedButton setSelected:NO];
}
[tempButton setSelected:YES];
selectedButton = tempButton;
}
I have a button that seems superfluous. I want to remove the button and place its functionality (animating a simple bar chart with associated labels) into a method that gets called upon return from a user input view controller.
It seemed simple enough to rename the existing IBAction method and put the call to the replacement method into the delegate method that handles the transition back to the original View controller. However, this produced an unexpected result.
Here's a screenshot. The button in question is the red one (Show Graph):
The problem is that before the change, the two labels (firstLabel and secondLabel) over the bars would appear after the bars animate into position. After the method change (the creation code is unchanged), the labels appear instantly upon return to the VC, before the bars animate.
Here's the original IBAction method attached to the button:
- (IBAction)goButtonAction:(id)sender
{
switch (goButtonKey)
{
case 0:
{
}
break;
case 1:
{
[self handleAvsAAction];
[self doTheMathAvsA];
[self makeBarChart];
}
break;
case 2:
{
[self handleCvsCAction];
[self doTheMathCvsC];
[self makeBarChart];
}
default:
break;
}
[self.goButton setUserInteractionEnabled:NO];
}
And here's the new method:
- (void) showGraph
{
switch (goButtonKey)
{
case 0:
{
}
break;
case 1:
{
[self handleAvsAAction];
[self doTheMathAvsA];
[self makeBarChart];
}
break;
case 2:
{
[self handleCvsCAction];
[self doTheMathCvsC];
[self makeBarChart];
}
default:
break;
}
[self.goButton setUserInteractionEnabled:NO];
}
Here's the code (from makeBarChart) that produces the bar animation and the labels. For brevity, I'm just showing one bar--the other is essential identical, except being driven by different data:
switch (thisRiser.tag)
{
case 1:
{
[self.chartView addSubview:firstLabel];
[firstLabel setHidden:YES];
[UIView animateWithDuration:.6
delay:.2
options: UIViewAnimationCurveEaseOut
animations:^
{
// Starting state
thisRiser.frame = CGRectMake(35, self.chartView.frame.size.height, barWidth, 0);
thisRiser.backgroundColor = startColor1;
// End state
thisRiser.frame = CGRectMake(35, self.chartView.frame.size.height, barWidth, -focusBarEndHeight);
thisRiser.backgroundColor = endColor1;
thisRiser.layer.shadowColor = [[UIColor blackColor] CGColor];
thisRiser.layer.shadowOpacity = 0.7;
thisRiser.layer.shadowRadius = 4.0;
thisRiser.layer.shadowOffset = CGSizeMake(5.0f, 5.0f);
thisRiser.layer.shadowPath = [UIBezierPath bezierPathWithRect:thisRiser.bounds].CGPath;
}
completion:^(BOOL finished)
{
firstLabel.frame = CGRectMake(thisRiser.frame.origin.x, thisRiser.frame.origin.y - 65, barWidth, 60);
[firstLabel.titleLabel setFont:[UIFont boldSystemFontOfSize:12]];
firstLabel.titleLabel.numberOfLines = 0;
firstLabel.titleLabel.textAlignment = NSTextAlignmentCenter;
[firstLabel setTitle:[NSString stringWithFormat:#"%#\n%.2f%%\nTime--%#",focusItemName,focusItemPercent,actualDurationFocusItem] forState:UIControlStateNormal];
firstLabel.backgroundColor = [UIColor clearColor];
[firstLabel setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[firstLabel setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[firstLabel setHidden:NO];
[firstLabel addTarget:self action:#selector(firstLabelAction:) forControlEvents:UIControlEventTouchUpInside];
[firstLabel setUserInteractionEnabled:YES];
[thisRiser setUserInteractionEnabled:YES];
// NSLog(#"Done!");
}];
}
break;
It doesn't seem reasonable that such a straightforward change would cause this effect. I've tried it several times to be sure I'm not breaking anything, and it seems that I am not.
Any ideas?
Try to put all the code from "completion:^(BOOL finished)" block, inside an if statement:
completion:^(BOOL finished) {
if (finished) {
// Do all that stuff, including make the label visible...
}
}
The problem was resolved by moving the call to the code from the former button action method (refactored into showGraph) from viewDidLoad into `viewDidAppear, as suggested by #rdelmar in a comment. Many thanks!
This is my code to change the flash mode on iphone.
In ios7.0 works: flashmode(0,1,-1)
In ios7.1 don't works: flashmode(0,0,0)
//UIImagePickerControllerCameraFlashModeOff = -1,
//UIImagePickerControllerCameraFlashModeAuto = 0,
//UIImagePickerControllerCameraFlashModeOn = 1
NSInteger flashMode = self.pickerReference.cameraFlashMode;
NSLog(#"flashmode %i",flashMode);
if (flashMode == UIImagePickerControllerCameraFlashModeAuto) {
[(UIButton *)sender setImage:[UIImage imageNamed:#"flashYesComposeButton.png"] forState:UIControlStateNormal];
self.pickerReference.cameraFlashMode = UIImagePickerControllerCameraFlashModeOn;
}
else if (flashMode == UIImagePickerControllerCameraFlashModeOn) {
[(UIButton *)sender setImage:[UIImage imageNamed:#"flashNoComposeButton.png"] forState:UIControlStateNormal];
self.pickerReference.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
}
else if (flashMode == UIImagePickerControllerCameraFlashModeOff)
{
[(UIButton *)sender setImage:[UIImage imageNamed:#"flashAutoComposeButton.png"] forState:UIControlStateNormal];
self.pickerReference.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
}
I ran into that bug before
The problem is that no matter what the real flash state is in ios 7.1, it always returns UIImagePickerControllerCameraFlashModeAuto. Funny thing is, if you set the flash mode to UIImagePickerControllerCameraFlashModeOff, the flash will really be off, but if you ask the state, it will still be UIImagePickerControllerCameraFlashModeAuto.
So I solved my problem by keeping my own "flashState". When, clicked, I manually change my own state and never trust the one sent back but the UIImagePickerController.
#property (nonatomic) UIImagePickerControllerCameraFlashMode flashMode;
when the button is clicked :
if (self.flashMode == UIImagePickerControllerCameraFlashModeAuto) {
//toggle your button to "on"
self.flashMode = UIImagePickerControllerCameraFlashModeOn;
}else if (self.flashMode == UIImagePickerControllerCameraFlashModeOn){
//toggle your button to "Off"
self.flashMode = UIImagePickerControllerCameraFlashModeOff;
}else if (self.flashMode == UIImagePickerControllerCameraFlashModeOff){
//toggle your button to "Auto"
self.flashMode = UIImagePickerControllerCameraFlashModeAuto;
}
I am using the UIImagePickerController with a custom camera overlay view and wish to add a custom button to toggle the flash mode between auto, on, and off. Here is the method the button calls:
- (void)didTapFlash:(id)sender
{
if (self.imagePickerController.cameraFlashMode == UIImagePickerControllerCameraFlashModeAuto)
{
[imagePickerController setCameraFlashMode:UIImagePickerControllerCameraFlashModeOn];
[self.flashButton setImage:[UIImage imageNamed:#"flashIconOn.png"] forState:UIControlStateNormal];
}
else if (self.imagePickerController.cameraFlashMode == UIImagePickerControllerCameraFlashModeOn)
{
self.imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
[self.flashButton setImage:[UIImage imageNamed:#"flashIconOff.png"] forState:UIControlStateNormal];
}
else if (self.imagePickerController.cameraFlashMode == UIImagePickerControllerCameraFlashModeOff)
{
self.imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
[self.flashButton setImage:[UIImage imageNamed:#"flashIconAuto.png"] forState:UIControlStateNormal];
}
}
The problem is this doesn't work. The value of self.imagePickerController.cameraFlashMode never changes once the controller is presented. The flash value can be changed before it is presented but, once it is, it will always return a value of 0 (Auto). The strange part is, even though the value doesn't change, the flash behaves as if it does so if I change the above code to:
- (void)didTapFlash:(id)sender
{
if (flashButton.tag == 0)
{
[imagePickerController setCameraFlashMode:UIImagePickerControllerCameraFlashModeOn];
self.flashButton.tag = 1;
[self.flashButton setImage:[UIImage imageNamed:#"flashIconOn.png"] forState:UIControlStateNormal];
}
else if (flashButton.tag == 1)
{
self.imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
self.flashButton.tag = -1;
[self.flashButton setImage:[UIImage imageNamed:#"flashIconOff.png"] forState:UIControlStateNormal];
}
else if (flashButton.tag == -1)
{
self.imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
self.flashButton.tag = 0;
[self.flashButton setImage:[UIImage imageNamed:#"flashIconAuto.png"] forState:UIControlStateNormal];
}
}
Everything works as expected. (the flashButton.tag is just storing the flash value)
Does anyone know what is happening here? Why does the value of cameraFlashMode always 0 (both in NSLog statements and when checked directly through the debugger) even though the flash is behaving as though it is set properly?
It seems to be a bug in latest iOS version,
you'll notice that it will work with enabling the flag of
self.picker.showsCameraControls = true
but it shows the native camera control to your overlayview, so i hacked it with this code:
self.picker.showsCameraControls = true
self.picker.cameraFlashMode = .On
self.picker.showsCameraControls = false
It is fast enough to not disturb user with the showing and hiding controls.
It Worked for me and i'm sure it will work in your case too!