How can I detect the selected state of a uibutton?
I have 7 buttons and I have made them to be able to toggle or select multiple buttons at a time.
I want to be able to tell which buttons are in a selected state when I push the done button.
So if M, T and W are selected then I want to be able to detect that when pushing done.
I currently put a tag on the button and then call a method to unselect or select multiple buttons.
self.repeatOccurrenceFrequencyWeeklyTF = [[UITextField alloc]init];
self.repeatOccurrenceFrequencyWeeklyTF.frame = CGRectMake(80, 80, 32, 32);
self.repeatOccurrenceFrequencyWeeklyTF.delegate = self;
self.repeatOccurrenceFrequencyWeeklyTF.background = [UIImage imageNamed:#"repeatWeekly"];
self.repeatOccurrenceFrequencyWeeklyTF.font = [UIFont fontWithName:#"SegoeWP" size:15];
self.repeatOccurrenceFrequencyWeeklyTF.textColor = [UIColor appGreyText];
[self.repeatOccurrenceFrequencyWeeklyTF setValue:[UIColor colorWithRed:153/255.0 green:153/255.0 blue:153/255.0 alpha:1.0] forKeyPath:#"_placeholderLabel.textColor"];
self.repeatOccurrenceFrequencyWeeklyTF.placeholder = #"1";
UIView *leftView1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 12, self.repeatOccurrenceFrequencyWeeklyTF.frame.size.height)];
self.repeatOccurrenceFrequencyWeeklyTF.leftView = leftView1;
self.repeatOccurrenceFrequencyWeeklyTF.leftViewMode = UITextFieldViewModeAlways;
self.repeatOccurrenceFrequencyWeeklyTF.rightViewMode = UITextFieldViewModeAlways;
self.keyboardToolbar = [self createInputToolbar];
self.repeatOccurrenceFrequencyWeeklyTF.inputAccessoryView = self.keyboardToolbar;
self.repeatOccurrenceFrequencyWeeklyTF.delegate = self;
self.repeatOccurrenceFrequencyWeeklyTF.keyboardType = UIKeyboardTypeNumberPad;
self.repeatOccurrenceFrequencyWeeklyTF.enabled = NO;
[self.view addSubview:self.repeatOccurrenceFrequencyWeeklyTF];
// Now, in your button action handler, you can do something like this:
- (void)mondayButtonTouch:(UIButton *)aButton withEvent:(UIEvent *)event
{
aButton.selected = !aButton.selected;
if(aButton.tag == 111) {
}
if(aButton.tag == 222) {
}
if(aButton.tag == 333) {
}
if(aButton.tag == 444) {
}
if(aButton.tag == 555) {
}
if(aButton.tag == 666) {
}
NSLog(#"dsfdfdfsdfs %ld", (long)aButton.tag);
[aButton setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
}
I would use a NS_ENUM (which helps to keep a nice and readable code) and a NSMutableArray to keep track of your selected buttons.
Declare a enum that looks something like this:
typedef NS_ENUM(NSInteger, Weekday) {
WeekdayMonday,
WeekdayTuesday,
WeekdayWednesday,
WeekdayThursday,
WeekdayFriday,
WeekdaySaturday,
WeekdaySunday
};
Then tag your buttons with the correct enum:
tuesdayButton.tag = WeekdayTuesday;
And check when you tap button if your enum exists in your array:
- (void)buttonTouch:(UIButton *)aButton withEvent:(UIEvent *)event
{
if ([array containsObject:#(aButton.tag)]){ //exists, remove it from array
[array removeObjectIdenticalTo:#(aButton.tag)];
}
}else{
[array addObject:#(aButton.tag)];
}
}
A possibility is to create an NSMutableArray named selectedButton. Do like this:
- (void)mondayButtonTouch:(UIButton *)aButton withEvent:(UIEvent *)event
{
aButton.selected = !aButton.selected;
if(!aButton.selected && selectedButton.containsObject(aButton.Tag)) {
[selectedButton removeObject:aButton.tag];
}
else if(aButton.selected && !selectedButton.containsObject(aButton.Tag)) {
[selectedButton addObject:aButton.tag];
}
// do your stuff here
}
Now on done button click you have all the button thats tags are selected will be trackable with selectedButton array.
You can use:
[self.view viewWithTag:yourTagHere]
you can use this :
for (UIButton *btn in [self.view subviews]) { // self.view (change it with your button superview)
if ([btn isKindOfClass:[UIButton class]] && [btn isSelected] == YES) {
// here you found the button which is selected
}
}
[self.view viewWithTag:yourTagHere] replace
Related
I have a text field that I want to have a keyboard like this when user start typing:
please also see this video: https://youtu.be/iU_jocny3N0
As you can see in this video there is a "ABC" key that helps user to switch from number pad to text. and also when press "123" in text the keyboard switchs from text to number pad. I am wondering how they do this?
The only solution that I found was adding a subview to keyboard like what described here:
Adding Done Button to Only Number Pad Keyboard on iPhone
but this way may not work when user uses custom keyboards. and also do not works for switching from text to number pad.
Or as another solution I know accessoryInputView but this is not like the video. It adds a toolbar above the keyboard.
Does someone knows the solutions that is used in this video?
I have added comma button to the keyboard,
Keyboard is also a simple UIView Which contains Controls
NOTE: This is old code was working in my old project Not tested in new projects
- (void) keyboardWillShow:(NSNotification *)note {
// create custom button
dispatch_async(dispatch_get_main_queue(), ^{
// Some code
UITextField *txt = (UITextField *)[self.view findFirstResponder];
if (txt.keyboardType == UIKeyboardTypeDecimalPad) {
UIButton * btnComma = [UIButton buttonWithType:UIButtonTypeCustom];
[btnComma setTag:15000];
UIView* keyboard = [self findKeyboard];
// btnComma.frame = CGRectMake(0, 162, 126, 54);
btnComma.frame = [self findKeySizeForView:keyboard];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")) {
[btnComma setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 20, 0)];
}
[btnComma setBackgroundColor:[UIColor colorWithHexString:#"CBD0D6"]];
btnComma.adjustsImageWhenHighlighted = NO;
[btnComma setTitle:#"." forState:UIControlStateNormal];
[btnComma setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btnComma.titleLabel setFont:[UIFont systemFontOfSize:35.0f]];
[btnComma addTarget:self action:#selector(commaBtnTapped) forControlEvents:UIControlEventTouchUpInside];
[keyboard addSubview:btnComma];
btnComma = nil;
}
});
}
- (UIView *) viewWithPrefix:(NSString *)prefix inView:(UIView *)view {
for (UIView *subview in view.subviews) {
if ([[subview description] hasPrefix:prefix]) {
return subview;
}
}
return nil;
}
This method for finding keyboard from UIWindow
- (UIView *) findKeyboard {
for (UIWindow* window in [UIApplication sharedApplication].windows) {
UIView *inputSetContainer = [self viewWithPrefix:#"<UIInputSetContainerView" inView:window];
if (inputSetContainer) {
UIView *inputSetHost = [self viewWithPrefix:#"<UIInputSetHostView" inView:inputSetContainer];
if (inputSetHost) {
UIView *kbinputbackdrop = [self viewWithPrefix:#"<_UIKBCompatInput" inView:inputSetHost];
if (kbinputbackdrop) {
UIView *theKeyboard = [self viewWithPrefix:#"<UIKeyboard" inView:kbinputbackdrop];
return theKeyboard;
}
}
}
}
return nil;
}
and For finding size of bottom right button
- (CGRect ) findKeySizeForView:(UIView *)view {
if (view != nil) {
UIView *uiKeyboardImpl = [self viewWithPrefix:#"<UIKeyboardImpl" inView:view];
if (uiKeyboardImpl != nil) {
UIView *uiKeyboardLayoutStar = [self viewWithPrefix:#"<UIKeyboardLayoutStar" inView:uiKeyboardImpl];
if (uiKeyboardLayoutStar != nil) {
UIView *uiKBKeyplaneView = [self viewWithPrefix:#"<UIKBKeyplaneView" inView:uiKeyboardLayoutStar];
if (uiKBKeyplaneView != nil) {
for (view in [uiKBKeyplaneView subviews]) {
CGPoint pointOrigin = view.layer.frame.origin;
if (pointOrigin.x <= 0 && pointOrigin.y == uiKBKeyplaneView.frame.size.height - view.frame.size.height && [[view description] hasPrefix:#"<UIKBKeyView"])
return view.layer.frame;
}
}
}
}
}
return CGRectZero;
}
I have a UIButton inside a UIView, when the UIButton is selected I would like have a background colour of dark gray...is this possible?
UIView *toolbar = [[UIView alloc]initWithFrame:CGRectMake(10, 50, 40, 160)];
[toolbar setBackgroundColor:[UIColor colorWithWhite: 0.70 alpha:0.5]];
toolbar.layer.cornerRadius = 5;
UIButton *penTool = [UIButton buttonWithType:UIButtonTypeCustom];
penTool.frame = CGRectMake(5, 0, 30, 30);
[penTool setImage:[UIImage imageNamed:#"pen-but" inBundle:currentBundle compatibleWithTraitCollection:nil] forState:UIControlStateNormal];
[penTool addTarget:self action:#selector(drawButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
penTool.autoresizingMask = UIViewAutoresizingNone;
penTool.exclusiveTouch = YES;
penTool.tag = 1;
[toolbar addSubview:penTool];
What if you can do this?
[button setBackgroundColor:[UIColor greenColor]
forState:UIControlStateSelected];
Let's give a great API for every state, not just selected, just like UIButton default API's ability to change image and title for every state.
BGButton.h
#import <UIKit/UIKit.h>
#interface BGButton : UIButton
- (void)setBackgroundColor:(UIColor *)backgroundColor
forState:(UIControlState)state;
#end
BGButton.m
#import "BGButton.h"
#implementation BGButton {
NSMutableDictionary *_stateBackgroundColor;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_stateBackgroundColor = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)setBackgroundColor:(UIColor *)backgroundColor {
[super setBackgroundColor:backgroundColor];
/*
* If user set button.backgroundColor we will set it to
* normal state's backgroundColor.
* Check if state is on normal state to prevent background being
* changed for incorrect state when updateBackgroundColor method is called.
*/
if (self.state == UIControlStateNormal) {
[self setBackgroundColor:backgroundColor forState:UIControlStateNormal];
}
}
- (void)setBackgroundColor:(UIColor *)backgroundColor
forState:(UIControlState)state {
NSNumber *key = [NSNumber numberWithInt:state];
[_stateBackgroundColor setObject:backgroundColor forKey:key];
}
/*
* state is synthesized from other flags. So we can't use KVO
* to listen for state changes.
*/
- (void)setSelected:(BOOL)selected {
[super setSelected:selected];
[self stateDidChange];
}
- (void)setEnabled:(BOOL)enabled {
[super setEnabled:enabled];
[self stateDidChange];
}
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
[self stateDidChange];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self stateDidChange];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
[self stateDidChange];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
[self stateDidChange];
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:touches withEvent:event];
[self stateDidChange];
}
- (void)stateDidChange {
[self updateBackgroundColor];
}
- (void)updateBackgroundColor {
NSNumber *key = [NSNumber numberWithInt:self.state];
self.backgroundColor = [_stateBackgroundColor objectForKey:key];
}
#end
You can use it like the default UIButton API
BGButton *button = [[BGButton alloc] init];
[button setBackgroundColor:[UIColor greenColor]
forState:UIControlStateSelected];
[button setBackgroundColor:[UIColor blueColor]
forState:UIControlStateHighlighted];
[button setBackgroundColor:[UIColor orangeColor]
forState:UIControlStateDisabled];
Even if you use
button.backgroundColor = [UIColor redColor];
You will stay safe, it will be translated into
[button setBackgroundColor:[UIColor redColor]
forState:UIControlStateNormal];
if you have this code
[self.view addSubview:toolbar];
then just implement your button selector
-(void)drawButtonTapped:(UIButton*)button{
if (button.selected) {
button.backgroundColor = [UIColor clearColor];
button.selected = NO;
}else{
button.backgroundColor = [UIColor darkGrayColor];
button.selected = YES;
}
}
I don't know why guys would go through such trouble when we have this functionality built-in inside UIButton. All you need to do is use UIButtonTypeSystem That's all.
[UIButton buttonWithType:UIButtonTypeSystem]
Seriously, there's nothing more to it. Have a look at it's behavior in the screenshots.
INTERFACE BUILDER
RUN TIME
Want to change color, set tintColor to color of your choice.
ADVANTAGES
Covers titles with dynamic lengths. Not applied on all button width.
When selected, title color is transparent, your background can be seen through, try to use an image as a background.
Let's hope you have at least iOS7 as deployment target. UIButtonTypeSystem was introduce with revised UI design guidelines of iOS7 and has been there for almost 3 years.
Good Luck!
I used a UIButton subclass here:
#import "CustomButton.h"
#interface CustomButton()
#property (nonatomic,strong) UIColor *originalColor;
#end
#implementation CustomButton
- (void)didMoveToSuperview
{
self.originalColor = self.superview.backgroundColor;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
self.superview.backgroundColor = [UIColor grayColor];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
if ([self hitTest:location withEvent:nil]) {
self.superview.backgroundColor = [UIColor grayColor];
self.originalColor = self.superview.backgroundColor;
}
else
{
self.superview.backgroundColor = self.originalColor;
}
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
self.superview.backgroundColor = self.originalColor;
}
#end
If you subclass your button from this class, It should give you the desired effect. This also gives you the highlight effect. If you wish you can disable it by removing the line on touchesBegan.
Just try to Override the UIButton with the following Method...
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
if (highlighted) {
self.backgroundColor = [UIColor darkGray];
}
}
I think you'll be want to change the selectedImage for flexibility not the background.
Add another image (e.g. pen-but-selected) in the project. Add this 2nd line for setImage:
[penTool setImage:[UIImage imageNamed:#"pen-but-selected" inBundle:currentBundle compatibleWithTraitCollection:nil] forState:UIControlStateSelected];
- (void)drawButtonTapped:(UIButton *)button {
button.selected = !button.selected;
}
If you still want to change background color. #jamil's answer would work. Make sure the buttonImage has transparent part so you can see the buttonBackground through the buttonImage.
Try using a boolean, or some other reference to the selection state of the button. You could also make use of a 'highlightColour' as well as the 'selectedColour' if you wanted closer control (should probably do this for better UX).
bool buttonIsSelected = false;
UIColor * selectedColour = [UIColor redColor];
UIColor * defaultColour = [UIColor blueColor];
UIButton * button = [UIButton new];
button.frame = CGRectMake(0,0,100,100);
button.backgroundColor = [UIColor redColor];
[self.view addSubview:button];
[button addTarget:self action:#selector(buttonTouchUp:) forControlEvents:UIControlEventTouchUpInside];
[button addTarget:self action:#selector(buttonTouchCancel:) forControlEvents:UIControlEventTouchCancel];
[button addTarget:self action:#selector(buttonTouchDown:) forControlEvents:UIControlEventTouchDown];
-(void)buttonTouchUp:(UIButton *)button {
if (buttonIsSelected){
buttonIsSelected = false;
button.backgroundColor = defaultColour;
} else {
buttonIsSelected = true;
button.backgroundColor = selectedColour;
}
}
-(void)buttonTouchCancel:(UIButton *)button {
button.backgroundColor = defaultColour;
if (buttonIsSelected){
button.backgroundColor = selectedColour;
}
}
-(void)buttonTouchDown:(UIButton *)button {
button.backgroundColor = selectedColour;
}
-(void)OnSelect:(UIButton*)button{
if (button.selected) {
button.backgroundColor = [UIColor blue];
button.selected = NO;
}else{
button.backgroundColor = [UIColor darkGrayColor];
button.selected = YES;
}
}
use the above this will work..
-(void)buttonTapped:(UIButton*)button{
button.selected =! button.selected;
if (button.selected)
button.backgroundColor = [UIColor grayColor];
else
button.backgroundColor = [UIColor clearColor];
}
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 created five buttons using for loop, it works well. Whenever i click restart button duplicate buttons created
-(void)buttonCreate {
for( int i = 0; i < 5; i++ )
{
oneBtn1 = [UIButton buttonWithType:UIButtonTypeCustom];
oneBtn1.frame = CGRectMake(316,i*-5+474,51,50);
[oneBtn1 setTag:i];
[oneBtn1 addTarget:self action:#selector(oneButton:) forControlEvents:UIControlEventTouchUpInside];
[oneBtn1 setImage:[UIImage imageNamed:#"1c.png"] forState:UIControlStateNormal];
[self.view addSubview:oneBtn1];
}
}
Restart button function:
-(void)restart {
[self buttonCreate];
}
I tried this one but it will remove only one button out of 5.
if(oneBtn1 != NULL) {
[oneBtn1 removeFromSuperview];
oneBtn1 = nil;
}
Problem is: How to remove duplicate buttons?
Create an array(NSMutableArray *buttonHolderArray) to hold outlets for all five buttons.
[buttonHolderArray addObject:oneBtn1];
Then you can remove/update the buttons as and when you need.
And once you dont want any button, empty the array itself. On top of this, if you wish to clear the view then simply call removeFromSuperView for all the buttons
I tried this one but it will remove only one button out of 5.
if(oneBtn1 != NULL) {
[oneBtn1 removeFromSuperview];
oneBtn1 = nil;
}
You are removing only one button, if you want to remove all then use
for ( UIButton *button in buttonHolderArray){
button removeFromSuperView];
}
You can remove by checking if the button is already created.
-(void)buttonCreate {
int tag_start = 500;
for( int i = 0; i < 5; i++ )
{
UIView * prevbtn = [self.view viewWithTag:tag_start + i];
if(prevbtn) {
[prevbtn removeFromSuperview];
}
oneBtn1 = [UIButton buttonWithType:UIButtonTypeCustom];
oneBtn1.frame = CGRectMake(316,i*-5+474,51,50);
[oneBtn1 setTag:tag_start + i];
[oneBtn1 addTarget:self action:#selector(oneButton:) forControlEvents:UIControlEventTouchUpInside];
[oneBtn1 setImage:[UIImage imageNamed:#"1c.png"] forState:UIControlStateNormal];
[self.view addSubview:oneBtn1];
}
}
use this before calling again restart method
for (UIButton *btn in self.view.subviews ) {
[btn removeFromSuperview];
}
Before the restart button clicked you can remove all the buttons from you view calling the method removeChildViewsWithKindOfClass
-(void)restart {
[self.view removeChildViewsWithKindOfClass:[UIButton class]];
[self buttonCreate];
}
-(void)removeChildViewsWithKindOfClass:(Class)classToRemove{
if (classToRemove==nil) return;
for (UIView *v in [self subviews]) {
if ([v isKindOfClass:classToRemove]) {
[v removeFromSuperview];
}
}
}
If you want to remove a specific button you can use the property tag that you have to set beforehand when you create your button and it allows you removing the button with a specific tag.
I am creating a small game with an interface that is quite similar to 4 Pictures 1 word. The current setup so far is as follows:
The user gets a 7 letter word generated at random.
There is an array which takes the 7 letters and then randomly populates them with other letters in 12 programatically created UIButtons:
for (int i=0; i< buttonCount; i++) {
int xpositiong = x + 37;
x = xpositiong;
isSeven ++;
restAt7 ++;
NSString *stringFromInt = [NSString stringWithFormat:#"%#",[arrayForRound objectAtIndex:i]];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(buttonSelected:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:stringFromInt forState:UIControlStateNormal];
button.titleLabel.font = [UIFont fontWithName:#"helvetica" size:19];
button.tag = i+10;
_letterButton = button;
if (restAt7 == 7) {
x = 47;
}
if (isSeven <= 6) {
button.frame = CGRectMake(x,333,40,40);
}
else
{
button.frame = CGRectMake(x,370,40,40);
}
[self.view addSubview:button];
}
There is also a second area of Buttons however these are static and constitute as "the word". When one of the 12 letters are selected it takes the tag of the selected button and populates one of the corresponding "word" buttons.
-(void)buttonSelected : (UIButton *)sender
{
NSLog(#"sender %i", sender.tag);
UIButton *button = (UIButton *)[self.view viewWithTag:sender.tag];
button.hidden = YES;
if ([_buttonOne.titleLabel.text isEqualToString: #" "]) {
// NSLog(#"button is nil");
[_buttonOne setTitle:sender.titleLabel.text forState:UIControlStateNormal];
[_buttonOne setTag:button.tag];
}
else if ([_buttonTwo.titleLabel.text isEqualToString:#" "])
{
[_buttonTwo setTitle:sender.titleLabel.text forState:UIControlStateNormal];
}
else if ([_buttonThree.titleLabel.text isEqualToString:#" "])
{
[_buttonThree setTitle:sender.titleLabel.text forState:UIControlStateNormal];
}
else if ([_buttonFour.titleLabel.text isEqualToString:#" "])
{
[_buttonFour setTitle:sender.titleLabel.text forState:UIControlStateNormal];
}
else if ([_buttonFive.titleLabel.text isEqualToString:#" "])
{
[_buttonFive setTitle:sender.titleLabel.text forState:UIControlStateNormal];
}
else if ([_buttonSix.titleLabel.text isEqualToString:#" "])
{
[_buttonSix setTitle:sender.titleLabel.text forState:UIControlStateNormal];
}
else if ([_buttonSeven.titleLabel.text isEqualToString:#" "])
{
[_buttonSeven setTitle:sender.titleLabel.text forState:UIControlStateNormal];
}
}
Right! So here is my question. If the user decides they have selected the wrong letter and wish to remove that letter they can press one of the 7 buttons to delete that letter. However I dont know how to un-hide the corresponding button which was originally populated with the letter...
I am confident it has something to do with retaining the Tag of the selected button however because each of the 7 buttons is assigned with Tag's I am not sure how to go about doing it.
EDIT:
I'll post up the solution that has worked. Also all functions have been rewritten with loops.
-(void)buttonSelected : (UIButton *)sender
{
NSLog(#"sender %i", sender.tag);
UIButton *button = (UIButton *)[self.view viewWithTag:sender.tag];
button.hidden = YES;
for (int i = 0; i < _wordButtonsArray.count; i ++) {
UIButton *selectedButton = [_wordButtonsArray objectAtIndex:i];
if ([selectedButton.titleLabel.text isEqualToString:#" "]) {
[selectedButton setTitle:sender.titleLabel.text forState:UIControlStateNormal];
[selectedButton setTag:button.tag];
return;
}
}
[self checkIfAnswerIsFinished:sender];
}
- (IBAction)clearButton:(id)sender
{
UIButton *button = (UIButton *)[self.view viewWithTag:[sender tag]];
button.hidden = NO;
for (int i = 0; i < _wordButtonsArray.count; i ++) {
if (button == [_wordButtonsArray objectAtIndex:i]) {
[button setTitle:#" " forState:UIControlStateNormal];
for (int letterButtonsIndex = 0; letterButtonsIndex < _letterButtonsArray.count; letterButtonsIndex++) {
UIButton *letterButton = [_letterButtonsArray objectAtIndex:letterButtonsIndex];
if (button.tag == letterButton.tag) {
button.tag = i;
letterButton.hidden = NO;
}
}
}
}
}
Works like a charm!
It seems like one way to do this is to make an NSArray that has 7 spaces, each filled with either the tag of the source button or -1. If a user taps on a -1, do nothing. If it is a number, set that tagged item to visible.
Also, your code is terribly not DRY (Don't Repeat Yourself) - you should spend some time thinking about programming and how you could use data structures more nicely. If you want more definite advice, just ask in the comments and I'll edit. :)
I can think of a couple of ways to accomplish this.
Solution 1:
Add your 12 buttons (bottom section) to an NSArray so when the user presses one of the 7 buttons (top section) you can iterate through that array and compare the titles. Something like this:
for (UIButton *button in buttonsArray) {
NSString *buttonTitle = [button titleForState:UIControlStateNormal];
// I'm assuming here that you already have the touched button tile
if ([buttonTitle isEqualToString:touchedButtonTitle]) {
button.hidden = NO;
}
}
Solution 2:
Create an array of 7 elements where you can match the "word" buttons with the tags of your letter buttons. Something like this:
-(void)buttonSelected : (UIButton *)sender
{
NSLog(#"sender %i", sender.tag);
UIButton *button = (UIButton *)[self.view viewWithTag:sender.tag];
button.hidden = YES;
if ([_buttonOne.titleLabel.text isEqualToString: #" "]) {
// NSLog(#"button is nil");
[_buttonOne setTitle:sender.titleLabel.text forState:UIControlStateNormal];
[_buttonOne setTag:button.tag];
// you know this is object One. Insert tag at position zero (arrays are zero-based)
self.topButtonsArray insertObject:[NSNumber numberWithInt:sender.tag] atIndex:0];
}
.
.
.
Hope this helps!