NSMutableArray of UIButton - ios

I have an NSMutableArray of buttons. When one of the buttons is pressed, I change it to a darker color. But I also want to change the background color of the other buttons so none of the previously pressed keep the darker color.
for(UIButton* u in menuButtons)
{
NSLog(#"test");
[u setBackgroundColor:[self byteColor:141.0 g:52.0 b:42.0] ];
}
But it doesn't even go into this loop. What should I be doing differently?

it doesn't even go into this loop means the buttons are not added properly to the array.Initialize the array and add the outlets first properly and the method will work

Related

iOS change custom bar button text color when the button becomes available

So I have a registration page (and multiple other places through the registration process where this will be implemented) that has a Next button, which is set up as a custom UIButton dragged onto the nav bar. As users enter in their registration information, I want to change the color of the text from grey when it is unavailable, to a custom green color. I've read some other threads, such as this one , but they haven't been any help. I think I'm doing what they told me to correctly, but I'm getting different results than I want. Right now my code looks like this:
-(void)checkCompletion
{
if( emailEntered && passwordEntered && [_password.text length] >= 5)
{
[_nextBarButtonItem setEnabled:YES];
[_nextButton setEnabled:YES];
[_nextButton.titleLabel setTextColor:[UIColor customGreen]];
[_nextButton setTintColor:[UIColor customGreen]];
[_nextBarButtonItem setTintColor:[UIColor customGreen]];
nextAvailable = YES;
}
else
{
nextAvailable = NO;
}
}
_nextBarButtonItem is the barButtonItem, and _nextButton is the UIButton I dragged onto the navigation bar, which is underneath _nextBarBUttonItem in the hierarchy. customGreen is a category with its header file #include'd into my prefix.pch, as I use the color throughout the app. This function gets called when textfields return and when the password is edited, so I can make the button available before the return key is pressed if users don't want to dismiss the keyboard first.
I have tried several methods, such as making the button my customGreen on the storyboard and disabling both the barButtonItem and the button itself underneath the barButtonItem in the hierarchy, hoping it would grey it out, but the button is still green, you just can't press it. I made the button grey on the storyboard, then call this function, but the text ends up changing to white instead of the green color. I tried explicitly defining the color as I set it, but I get the same result. I do not want my back button to turn this green color, only the next button when it becomes available to press.
Any ideas what I'm doing wrong?

Action not happening when tapping UIButton

I have a UIButton placed on a UIImageView and UILabel.
When i press down the button i want an image to show in the UIImageView and the text color of the UILabel to be changed, and when i pull up my finger i want the image to disappear and the text color of the UILabel changed back to black.
- (void)highlightActivity:(id)sender {
activityImage.image = [UIImage imageNamed:[[NSMutableString alloc] initWithString:activityName]];
activityLabel.textColor = activityColor;
}
- (void)deHighlightActivity:(id)sender {
activityLabel.textColor = [UIColor blackColor];
activityImage.image = nil;
}
It works fine when i press the button and then release, but i have a problem when tapping the button, the image isn't showing at all and the text color isn't changing.
Any ideas how to make it happen when tapping too?
Thanks,
Naor.
I think the problem is you attach both
Touch Up inside and outside on deHighlightActivity.
Because, when you pressed the button, you will release (touch up) the button eventually, if you put both touch up inside and outside on deHighlightActivity, that action will be called every time. So that your tapping action calls deHighlightActivity as well.
I don't know what exactly you are trying to do here, but looks like you have some conflicts on your design.

Custom UIButton inside a UITableView keeps highlighted after being pressed

I have implemented a custom UIButton, posted in cocoacontrols.com:
http://cocoacontrols.com/platforms/ios/controls/imageless-gradient-buttons
I´ve just converted the project to ARC and setted up the buttons. They work, but after being pressed once, they keep they highlighted gradient.
To set them up, I just changed the class on both storyboard and on the IBOutlets and I´ve selected the gradient I wante on viewDidLoad.
Any idea on what could be the problem?
EDIT: I've been spending more time with it and it appears to be that the problem only happens when the button is on a UITableView. It works OK when it is on a UIViewController
EDIT #2: according to the NSLogs, when the container is a UIViewController, the gradient is back to normal when a button is pressed:
2012-05-26 10:53:17.950 GradientButtons[11507:f803] highlighthed
2012-05-26 10:53:18.040 GradientButtons[11507:f803] highlighthed
2012-05-26 10:53:18.140 GradientButtons[11507:f803] Normal
but when the container is a UTableViewController, the button remains with the highligthed gradient:
2012-05-26 10:55:20.969 GradientButtons[11507:f803] highlighthed
2012-05-26 10:55:21.069 GradientButtons[11507:f803] highlighthed
I've checked the viewContentMode and it is all the same for all the buttons, UIView and UITableView (Scale to Fill). Changing it to redraw doesn't change behaviour.
There's the check responsible for normal/highlighted gradient drawing:
if (self.state == UIControlStateHighlighted)
gradient = self.highlightGradient;
else
gradient = self.normalGradient;
You need to set the breakpoint or add NSLog's to see whether the normal gradient is selected there. If it doesn't, the next step would be to override the normal UIButton drawRect adding the state log. Use it instead of the colored buttons to see whether that's a standard UIButton behavior for your table (e.g. you might keep the cell highlighted after the button is clicked which forces the subviews also to be highlighted)
Based on your log i found it interesting an reproduced the problem, it seems to be a race condition for the highlighted state to be caught at touchesEnded (try to hold a click for about a second - the state will be normal at touchesEnded). The reason needs to be investigated further, as a workaround you could use the following code:
-(void) setHighlighted:(BOOL)highlighted
{
NSLog(#"setHighlighted %#", highlighted ? #"Y": #"N");
[super setHighlighted:highlighted];
[self setNeedsDisplay];
}

How to set the UIButton state to be highlighted after pressing it

I have a typical requirement wherein I need to keep a button in highlighted state after pressing it. I need to perform a task which should work only when a button is in highlighted state. Actually I am setting a button state to highlighted programatically.
[sender setHighlighted:YES];
And once the button is in highlighted state i need to perform another action.
- (IBAction)changeState: (UIButton*)sender
{
if (sender.highlighted == YES)
{
[self performSomeAtion:sender];
}
}
But, to my horror, whenever I press any button, the above condition is becoming true and the action is being performed repeatedly. Is there any way in which i can keep a UIButton's state to be highlighted after pressing it?
EDIT - Actually I need to perform 3 different actions for 3 different states of the button. I am already making use of selected state and normal state. Now, I need to make use of the highlighted state.
[sender setSelected:YES];
or you can simulate this effect with two image for your UIButton (notselectedimage.png and selectedimage.png), then keep track button state with a BOOL variable like BOOL buttonCurrentStatus;. Then in .h file:
BOOL buttonCurrentStatus;
and in .m file
// connect this method with Touchupinside function
- (IBAction)changeState:(UIButton*)sender
{
/* if we have multiple buttons, then we can
differentiate them by tag value of button.*/
// But note that you have to set the tag value before use this method.
if([sender tag] == yourButtontag){
if (buttonCurrentStatus == NO)
{
buttonCurrentStatus = YES;
[butt setImage: [UIImage imageNamed:#"selectedImage.png"] forState:UIControlStateNormal];
//[self performSomeAction:sender];
}
else
{
buttonCurrentStatus = NO;
[butt setImage:[UIImage imageNamed:#"notSelectedImage.png"] forState:UIControlStateNormal];
//[self performSomeAction:sender];
}
}
}
- (void)mybutton:(id)sender
{
UIButton *button = (UIButton *)sender;
button.selected = ![button isSelected]; // Important line
if (button.selected)
{
NSLog(#"Selected");
NSLog(#"%i",button.tag);
}
else
{
NSLog(#"Un Selected");
NSLog(#"%i",button.tag);
}
}
The highlighted state is used to highlight the button while it is being touched. A touch down event in the button highlights it. You should use the "selected" state instead.
If what you want to do is perform an action after the button is pressed, don't attach your method to the state change event, attach your method to the TouchUpInside event.
I just find a way, so I share it, just in case...
I kept my UIButton and set one image for each state (so you could go up to a 4 states button).
I set the UserInteractionEnabled to NO -> This button won't receive any touch.
The purpose of this first button is to show a state
I create a second custom UIButton with the same frame than the first one. For this one, none image will be set for the state (it's a fully transparent button). The purpose of this button is to catch the touch event. So I added a target to this button on the TouchUpInside event. And then when the event is fired, I change the state of the first button to Disabled, Highlighted, Selected, or none of these state (= Default state).
Everything is working like a charm!
The way you describe it, you'd be better off subclassing UIView to create your own three-state button.
Actually, you should even implement your own multistate buttonView, and manage the state it's in internally via an array of PNG for the looks and an array of states to know how many times it's been pressed.
Use [sender setSelected: YES];, I think it will be useful to you.
UIButton *btn_tmp=sender;
if(!(btn_tmp.selected))
{
[btn_temp setHighlighted:YES];
}
For iOS 7 only: you should consider setting the image renderMode to UIImageRenderingModeAlwaysTemplate. You can then use the tintColor to represent various states.
see How to apply a tintColor to a UIImage?
and
see Tint a UIView with all its subviews
The solution is tricky but it's possible.
The problem is that you tried to change the highlighted status in the button action method, which I suppose makes a clean up or check process at the end of the action and switch the highlighted status. When you try to debug it you get the highlighted = 1 but it will change at the end.
Strange but your "3 statuses button" is sometimes useful, when you'd like to keep a button in "highlighted" mode like the "selected" mode to get different action depending on the 3 statuses.
The only problem that you couldn't analyze this or switch it to highlighted mode in the button action method as this will switch to highlighted mode immediately as the user push it AND switch it back at the end.
The solution is using a dispatch.
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[theButton setHighlighted:YES];
});
This will do the trick and you could use the 3 statuses.
According to apple, UIButton has a property of imageView:
Although this property is read-only, its own properties are read/write. Use these properties to configure the appearance and behavior of the button’s view
This means that you can set in the IB (in the storyboard) a picture for this button and set the highlighted picture:
Open the Attribute inspector.
Under Button section, choose an image.
In the same section, change the State Config to Highlighted. Notice the image you chose under default is now gone and now you can set a new picture for the Highlighted.
Now you have a button with 2 state config and all you have to do during runtime to change the button.highlighted = true. Also, check the UIControl under Configuring the Control’s Attributes for more states.
You can also do it programatically as follows:
Swift (and almost the same in Objective-C):
// Setting the highlighted image
self.someButton.imageView?.highlightedImage = UIImage(named: "imageNameFromImageAssest")
// someButton will now some the highlighted image and NOT the image set in the IB
self.someButton.imageView?.highlighted = true

Adding a UISegmentedControl to UISearchBar instead of Scope Buttons

I'd like to add scope buttons below my UISearchBar. However I cannot change the tint color of the built in scope buttons.
Instead, I added a UISegmentedControl to my tableViewHeader. This works well enough, but it only shows when I am not typing into the UISearchbar. Not very convenient.
When I enter text into the UISearchBar, the table and segmented controls become hidden by the "no results shown" semi-opaque black layer. Once results start showing my segmented control disappears altogether, and only cells with results show.
I want to make the segmented control clickable during text entry into the search bar.
Do you know of any way to do the following?
make UISegmentedControl move with UISearchBar when text is being entered, or
show UISegmentedControl whilst search results are displayed on the UITableView
Thank you
try
#implementation UISearchBar (subviewAccess)
- (UISegmentedControl *)scopeBar {
for (UIView *v in [self subviews]) {
if ([v isKindOfClass:[UISegmentedControl class]])
return v;
}
return nil;
}
#end
to get hold of the segmented control you want, and tint it from there
(it's currently at index 0, but that's definitely not for sure)
there is no "private API" being used, so apple should be okay with it,
but note if they changed their view layout (unlikely), this could break,
which would have the side effect of your tint disappearing, you should
access the rest of its state through the standard search bar APIs

Resources