I have a view that is accessible in two different ways. I have an if statement that determines in which case a button should be displayed.
if([Recipes entryExists:[note recipeIdentifier]]){
[buttons insertObject:btnRemoveFave atIndex:0];
[btnPrefs setHidden:NO];
} else {
[buttons insertObject:btnAddFave atIndex:0];
[btnPrefs setHidden:YES];
[btnPrefs setEnabled:NO];
}
I have placed a break point in the in both conditions of the if statement. When code enters the else condition, the lines that 'setHidden' and 'setEnabled' ARE both executed, yet the button is still visible AND enabled.
Any ideas as to why I can't disable the button? Thanks!
Can you check if you are creating a new instance of the button each time you call the statement?
If you are using a local variable instead of instance, use the tag property to identify your button, so you can find it in the buttons array.
Besides that, I prefer using alpha=0.0 instead of hidden=YES.
Good luck.
Use below code. It's working for me.
For Remove:
[btnPrefs removeFromSuperview];
Then Add:
[self.view addSubview:btnPrefs];
Related
I'm trying to get back into iOS programming, but it's been a while so I've kind of lost it.
I'm trying to make a simple single view game. I have four buttons. Button 1, button 2, button 3, and button 4.
What I need to happen is: When I press a button, the button gets selected, and then I want the user to be able to press any other button, which will then lead to an if statement that I'm gonna code later.
Also, I want the user to be able to unselect the previously selected button by just clicking it again. So that he or she can select another button of their choice, to start with.
I'd really appreciate this simple setup of code, since I have no clue how I'm gonna do it.
The idea is to change the state of the other buttons in the selector (IBAction) for the 1st button after it is pressed and control goes back to the user.
Whatever happens to the 3 button seems to imply that you just want them set or unset then evaluated at the same time - the more appropriate class to use is a UISwitch so you can set - unset them all at once without triggering an action. Of course you may use buttons if you wish but typically each button will trigger a selector instead of your code patiently waiting for the user to make up his mind in setting the options before your code starts again.
In case you forgot:
- (void)viewDidLoad {
[super viewDidLoad];
[Button1 addTarget:self action:#selector(Button1_pressed:)
forControlEvents:UIControlEventTouchUpInside];
[Button2 addTarget:self action:#selector(Button2_pressed:)
forControlEvents:UIControlEventTouchUpInside];
Button2.enabled = NO;
[Button3 addTarget:self action:#selector(Button3_pressed:)
forControlEvents:UIControlEventTouchUpInside];
Button3.enabled = NO;
.... }
-(IBAction) Button1_pressed:(ID) sender {
Button2.enabled = YES;
Button3.enabled = YES;
Button4.enabled = YES;
}
the above functionality can be easily achieved by managing flag to know if button is already selected or not.
set slected=1; when user press the button,
selecting again will change flag to selected=0 will help you to get selected status of button easily.
Take a BOOL variable isSelected.
isSelected = ! isSelected;
if(isSelected){
button.enabled = NO;
}
else{
button.enabled = YES;
}
I have a button hooked up in the storyboard to a method onButtonPress. In that method I call [pressedButton removeFromSuperview] but the view is not removed. I have even tried [_scrollView setNeedsDisplay]; and [_scrollView setNeedsLayout]; with no luck. I am assuming this is a restriction on being able to remove the button I have pressed. Is there a way I can signal to the view controller to call a method in the future to remove this button?
you can just hide it,
- (IBAction)celebritiesButtonPressed:(id)sender {
self.button.alpha = 0;
//[self.peopleButton removeFromSuperview]; //as you intend
}
Nevermind, actually. I was making a silly mistake.
The view I was pressing is part of a custom table I implemented to avoid the tableview in the scrollview. What I was doing was removing all the table cells from the table then re-adding them with the exception of the one that was clicked. Except right before I looped through the array which held the views and called [view removeFromSuperview], I removed the view I pressed from that array. Therefore, it was never calling that method.
So I was doing
[_taskViewCells removeObject:t];
for (id taskViewCell in _taskViewsCells) {
[taskViewCell removeFromSuperview];
// Remove all the task views
}
Pretty silly...
I need to show one view or another in a single function.
Is there any way to do this without doing:
[label1 setHidden:YES];
[label2 setHidden:YES];
[label3 setHidden:YES];
e.g. in one function?
In android I would create two absolute layouts and show one or the other, I am searching something similar on iOS.
You can add those UILabel inside a UIView, and then when you need them to hide, you can set that UIView to be hidden.
You hide all subviews in a single line.
[view.subviews makeObjectsPerformSelector:#selector(setHidden:)
withObject:[NSNumber numberWithBool:YES]];
Similarly if you want to remove all subviews you can remove them in single line
[view.subviews makeObjectsPerformSelector:#selector(removeFromSuperView)];
I have a few UIButtons at the bottom of my app's main view. These buttons intermittently don't highlight when a user taps them but their target methods always get called. I've discovered it's Control Center's gesture recognizer getting in the way of UIButton's highlighting. If I move the containing view up toward the middle of the screen everything functions as designed.
The issue is reported here https://devforums.apple.com/message/865922
As a workaround I've tried setting the highlighted state by hand with the target method. This seems to have the same effect of allowing the UIButton to highlight normally.
Any ideas how to work around this without redesigning these controls to appear elsewhere in the app?
Perhaps I use a standard view and add all the methods for touch interaction by hand? How would I do that? Is it even worth exploring?
I've found a pretty simple workaround for this. Using standard properties like .highlighted = YES and .selected = YES doesn't seem to work within that bottom band. Instead of setting the highlighted state, I just set the background image of the button to the highlighted state with an unperceived delay BEFORE we call the final method.
[self.stopRecordingButton setImage:[UIImage imageNamed:#"stopRecordingButton"] forState:UIControlStateNormal];
[self.stopRecordingButton setImage:[UIImage imageNamed:#"stopRecordingButton-highlighted"] forState:UIControlStateHighlighted];
[self.stopRecordingButton addTarget:self action:#selector(stopRecordingDelay) forControlEvents:UIControlEventTouchUpInside];
-(void)stopRecordingDelay
{
[self.stopRecordingButton setImage:[UIImage imageNamed:#"stopRecordingButton-highlighted"] forState:UIControlStateNormal];
[self performSelector:#selector(stopRecording) withObject:nil afterDelay:0.025f];
}
- (void)stopRecording
{
[self.stopRecordingButton setImage:[UIImage imageNamed:#"stopRecordingButton"] forState:UIControlStateNormal];
//Do real stuff
}
I recently ran into the same problem and search everywhere for an answer. This is what worked for me. It was a combination of two things, the UINavigationController back swipe gesture and the iOS 7 control center gesture (up swipe from bottom of the screen).
Disable the back swipe gesture if on a UINavigationController:
in viewDidLoad:
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
Set the control center gesture to only show an up arrow instead of showing the control center first. You can do this by overriding the following UIViewController method:
- (BOOL)prefersStatusBarHidden {
return YES;
}
Hope this helps!
I've posted a fix for this issue that brings the highlight back described in this question. The highlight is fixed by subclassing UIButton and overriding pointInside: to catch touch events
If you have a button that's covering the whole bottom of the screen you may run into an issue where only the left part has this delay.
In order to normalize feedback time for the whole button one might use the following solution
(an improved version of Aaron Shekey's):
NSDate *touchDownTime;
- (void)touchDown
{
self.alpha = 0.7;
touchDownTime = [NSDate date];
}
- (void)touchUpInside
{
// basically at least 80ms feedback is guaranteed this way
// note: timeIntervalSinceNow returns negative
NSTimeInterval feedbackTimeLeftToShow =
MAX(0.08 + [touchDownTime timeIntervalSinceNow], 0.001);
[self performSelector:#selector(touchUpInsideAfterFeedback)
withObject:nil
afterDelay:feedbackTimeLeftToShow];
}
- (void)touchUpInsideAfterFeedback
{
self.alpha = 1;
}
note: performSelector may do well with negative delay values, but better be safe than sorry
I have been creating "if/then" apps for android and now my boss want me to do the same for his iPad. I just need to figure out how to code so that when the buttons are clicked, it hides the current view (text and button) and reveals the next set of text and buttons.
Make sure your two sets of text/buttons are in two UIViews (I will refer to these as 'viewOne' and 'viewTwo'), when you want to swap your views, use this code:
[viewOne setHidden:[viewTwo isHidden]];
[viewTwo setHidden:![viewTwo isHidden]];
It's not the most understandable way to do this, but it's one of the shortest.
For something easier to read:
if ([viewOne isHidden]) {
[viewOne setHidden:NO];
[viewTwo setHidden:YES];
} else {
[viewOne setHidden:NO];
[viewTwo setHidden:YES];
}
Either will work, it just depends on how you like to write your code.