Can I add OBject of button to NSMutableArray? - iphone

I am trying to create number of buttons on view programatically and for that I need array, so can I add button object in NSMutableArray?

Yes you can do that see the following code
// Create buttons for the sliding menu. For simplicity I create 5 standard buttons.
NSMutableArray *buttonArray = [[NSMutableArray alloc] init];
for(NSInteger i = 0; i < [self.slideMenuArray count]; i++)
{
// Rounded rect is nice
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
NSString *title=[slideMenuArray objectAtIndex:i];
[btn setFrame:CGRectMake(0.0f, 4.0f, 90.0f, 20.0f)];
[btn setTitle:[NSString stringWithString:title] forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor clearColor]];
[btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[[btn titleLabel] setFont:[UIFont systemFontOfSize:12]];
[btn addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
UIImage *backgroundView;
if(i==0)
backgroundView= [UIImage imageNamed:#"btnclk.png"];
else
backgroundView= [UIImage imageNamed:#"btn.png"];
[btn setBackgroundImage:backgroundView forState:UIControlStateNormal];
[buttonArray addObject:btn];
}
You can retrieve the added button objects like this-
for(int i = 0; i < [buttonArray count]; i++)
{
UIButton *btn = [buttonArray objectAtIndex:i];
// Move the buttons position in the x-demension (horizontal).
CGRect btnRect = btn.frame;
btnRect.origin.x = totalButtonWidth;
[btn setFrame:btnRect];
}

sure you can, and remember that when you do, every button or other object will be retained bu the array and released when you remove it from the array...

Yes, NSMutableArray can hold any objects

Related

how to set the scroll view contentsize dynamically?

I had an application in which i am setting the content size of the scroll view dynamically according to the number of buttons which i am creating from an array.like this `
for(int i =0;i<[sarray count];i++)
{
NSMutableDictionary *dicttable=[sarray objectAtIndex:i];
NSString *head=[dicttable objectForKey:#"cat"];
btn= [UIButton buttonWithType:UIButtonTypeCustom];
int j=i+1;
btn.frame = CGRectMake((j-1)*87,0,87, 44);
[btn setBackgroundImage:[UIImage imageNamed:#"bar.png"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:#"bar_hvr.png"] forState:UIControlStateSelected];
btn.backgroundColor = [UIColor clearColor];
btn.titleLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:14];
btn.titleLabel.textColor = [UIColor whiteColor];
[btn setTitle:head forState:UIControlStateNormal];
btn.tag = i;
[btn setShowsTouchWhenHighlighted:YES];
[Scroller addSubview:btn];
[btn addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
if(btn.tag==0)
{
sendActionsForControlEvents:UIControlEventTouchUpInside];
}
else
{
btn.selected=NO;
}
}
}
[Scroller setContentSize:CGSizeMake([sarray count]*85, 44)];
`
but here the problem is after the last button also the scroll view scrolls .it need not to be happend,i need the scrolling ends with last button on the view,can anybody help me on this
set scrollview bounces to NO
scrollView.bounces = NO;
yes as you said it looses the smoothness. But no other choice. If you found any sol please update the answer.
hey i am sending you complete example to make button dynamicay and seting the content size scrollview on number of count ,i had just given u one example code u have to set the size of frame of button as u requried
UIScrollView *scroll_View=[[UIScrollView alloc]initWithFrame:self.view.bounds];
[self.view addSubview:scroll_View];
int y=0;
for(int i =1;i<10;i++)
{
// NSMutableDictionary *dicttable=[sarray objectAtIndex:i];
// NSString *head=[dicttable objectForKey:#"cat"];
UIButton* btn= [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(y,89,100, 50);
[btn setBackgroundImage:[UIImage imageNamed:#"bar.png"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:#"bar_hvr.png"] forState:UIControlStateSelected];
btn.backgroundColor = [UIColor clearColor];
btn.titleLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:14];
NSString *str=[NSString stringWithFormat:#"%d",i];
btn.titleLabel.textColor = [UIColor whiteColor];
[btn setTitle:str forState:UIControlStateNormal];
btn.tag = i;
[btn setShowsTouchWhenHighlighted:YES];
[scroll_View addSubview:btn];
[btn addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
y=110*i;
}
[scroll_View setContentSize:CGSizeMake(y, 400)];
enjoy coding
You just declare one yMargin variable of type CGFloat and initialize it with some required value as 0. Now every time whenever you are adding a new subview vertically do y+=lbl.frame.size.height;
Now setContentSize:CGSizeMake([sarray count]*85, y margin+someRequiredMargin)];
(someRequiredMargin - you want to add below )

Creating UIButtons dynamically - Logic Error

I have a NSMutableArray, and i have saving some string values in it. The size of the NSMutableArray could vary from 2-5 (Meaning it might have 2 -5 string values stored in it).
Depending on the count of the NSMutableArray i need to initialize UIBUttons and then set the value of the String stored init to the buttons title.
int numberOfButtonsToBeInitialize= [mutableArr count];// we are finding the number of buttons to be initialize and we assign it to a variable.
Now i need to create buttons (what ever the number returned by numberOfButtonsToBeInitialize)
How can i do this ?
for(int i=0;i<numberOfButtonsToBeInitialize;i++){
//init the button
UIButton *bout = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//set the title
[bout setTitle:[mutableArr objectAtIndex:i] forState:UIControlStateNormal];
[bout addTarget:self action:#selector(event:) forControlEvents: UIControlEventTouchUpInside];
[self.view addSubview:bout ];
//then you can set the position of your button
[bout setFrame:CGRectMake(70,3, 40,40)];}
Try this:
NSMutableArray *myButtonsArray = [[NSMutableArray alloc] initWithCapacity:0];
UIButton *tmpButton;
for (NSString *bTitle in mutableArr)
{
tmpButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[tmpButton setTitle:bTitle forState:UIControlStateNormal];
// Any additional setup goes here
[myButtonsArray addObject:tmpButton];
}
Now you have an array with all the buttons. You can just iterate this array and add any button as a subview in your main view.
You need a for loop. For example:
float buttonWidth=50;
float margin=5;
for (int index=0; index<numberOfButtonsToBeInitialize;index++)
{
UIButton* button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
NSString* buttonTitle=[mutablearr objectAtIndex:index];
[button setTitle:buttonTitle forState:UIControlStateNormal];
[button setFrame:CGRectMake(0+(buttonWidth+margin)*index, 0, buttonWidth, 30)];
[button setTag:100+index];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
In this case we layout buttons in a row(horizontally). Adjust to your own preferences

not able to change property of objects of NSArray

I have a:
#property(nonatomic, retain) NSArray * buttonsArray;
...
...
#synthesize buttonsArray;
when the view loads I initialize it as:
buttonsArray = [[NSArray alloc] initWithObjects:
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
[UIButton buttonWithType:UIButtonTypeRoundedRect],
nil];
// this code places the buttons from buttons array on top of the images in my view. I placed those images in an array called imagesArrayV;
int counter = 0;
counter=0;
for (UIButton *button in buttonsArray) {
button = [buttonsArray objectAtIndex:counter];
[button setTag:counter]; // *********
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(test:) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Hello" forState:UIControlStateNormal];
UIImageView *tempImage = [imagesArrayV objectAtIndex:counter];
CGRect tempRect = tempImage.frame;
button.frame = tempRect;
[self.ViewMainV addSubview:button];
counter++;
}
the purpose of this is to save time creating all the buttons in xcode and creating the connections.
I posted a picture so that you can get an idea...
Anyways the method that get's executed when clicking a button is:
-(void) test: (id) sender{
UIButton*btn = (UIButton*)(sender);
int tagnumber = [btn tag];
NSLog(#"%i",tagnumber);
}
why is it that when I press on the buttons the tag is equal to 0 when I set it to something else ( look for : // ********* ) when creating the button. Moreover when I run this method:
-(void) someOtherMethod{
int counter = 0;
for (UIButton *button in buttonsArray) {
button = [buttonsArray objectAtIndex:counter];
button.alpha = 0;
button.titleLabel.text = #"I change the title";
counter++;
}
}
the buttons that I previously added do not change at all. also the alpha does not change. I don't know what button's I am changing when I run the last method.
Just below the line where you set the tag, you have the line button = [UIButton buttonWithType:UIButtonTypeRoundedRect];. This overwrites the button obviously. The action is then added to the newly created button, the buttons in the array are left unaltered.
Personally I would rewrite the code as follows:
for (int counter = 0; counter < numberOfButtons; ++counter) {
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTag:counter];
[button addTarget:self action:#selector(test:) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Hello" forState:UIControlStateNormal];
UIImageView *tempImage = [imagesArrayV objectAtIndex:counter];
CGRect tempRect = tempImage.frame;
button.frame = tempRect;
[self.ViewMainV addSubview:button];
[buttonsArray addObject:button];
}
This also avoids populating the array hardcoded, for more flexible, less error-prone code.
try using this code instead of the third section above:
for(int i=0;i<[buttonsArray count];i++){
UIButton *button=[buttonsArray objectAtIndex:i];
[button addTarget:self action:#selector(test:) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Hello" forState:UIControlStateNormal];
UIImageView *tempImage = [imagesArrayV objectAtIndex:counter];
button.frame = tempImage.frame;
button.tag =i;
[self.ViewMainV addSubview:button];
}
one of the issues, is that you were setting the tag on button, then replacing the button instance on the next line.
This looks suspicious, and you do it twice:
for (UIButton *button in buttonsArray) {
button = [buttonsArray objectAtIndex:counter];
You should not modify the loop enumeration variable button inside the loop. You simply use button as it is.
IOW, you either do:
for (counter = 0; counter < buttonsArray.count; counter++)
{
UIButton *button = [buttonsArray objectAtIndex: counter];
button.alpha = 0;
// etc...
or you simply get rid of counter and do:
for (UIButton * button in buttonsArray)
{
button.alpha = 0;
// etc...

How to set the background image for the particular index of the button in iPhone?

I have created buttons dynamically and now I want to set the background for a particular index of the buttons.
Here is my sample snippet:
In the interface file:
UIButton *answerBtn;
#property (nonatomic, retain) UIButton *answerBtn;
for(int i = 0; i < [myArray count]; i++) {
answerBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[answerBtn setFrame:CGRectMake(30, x, 260, 40)];
answerBtn.tag = i;
[answerBtn setTitle:[answerList objectAtIndex:i] forState:UIControlStateNormal];
[self.view addSubview: answerBtn];
}
In my case, I want to set the button background in different methods.
-(void) custom Method
{
if(indexValue == correctIndex) // Values are 2
{
// so I want to set the background image for the second button
[answerBtn setBackgroundImage:[UIImage imageNamed:#"selected_correct_answer.png"] forState:UIControlStateNormal];
}
}
But it doesn't set the corresponding index, so how can I do that?
Try this
for(int i = 0 ; i < [myArray count] ; i++ )
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTag:i];
[btn setFrame:CGRectMake(30, x, 260, 40)];
[btn addTarget:self action:#selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (IBAction) btnClicked::(id)sender
{
UIButton *btnTapped=(UIButton *)sender;
for(UIView *btn in self.view.subviews)
{
if([btn isKindOfClass:[UIButton class]])
{
UIButton *btnComp = (UIButton*)btn;
if(btnComp.tag == btnTapped.tag)
[btnComp setBackgroundImage:[UIImage imageNamed:#"selected_correct_answer.png" forState:UIControlStateNormal];
else
[btnComp setBackgroundImage:[UIImage imageNamed:#"default_image.png" forState:UIControlStateNormal];
}
}
}
Use -(void)custom:(id)sender instead of -(void)custom.
In the sender you can have the index of the button.
UIButton *answerBtn = (UIButton *)[self objectWihTag:1]

UIButton handling in array

I created array of buttons, but i am not see, that buttons handles touch events ( buttonEvent: not calls)
This my code - is it not correct ?
- (void)loadView{
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:screenRect];
[backgroundImageView setImage:[UIImage imageNamed:#"background.png"]];
backgroundImageView.opaque = YES;
self.view = backgroundImageView;
[backgroundImageView release];
CGRect brandRect = CGRectMake(90, 25, 140, 70);
UIImageView *brandImageView = [[UIImageView alloc] initWithFrame:brandRect];
[brandImageView setImage:[UIImage imageNamed:#"brand.png"]];
[self.view addSubview:brandImageView];
buttons = [NSMutableArray array];
int y = 100;
for ( int i = 0 ; i < 5; i++ ){
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(20, y, 280, 50)];
if ( i == 0 ){
[button setBackgroundImage:[UIImage imageNamed:#"select_active.png"] forState:UIControlStateNormal];
} else {
[button setBackgroundImage:[UIImage imageNamed:#"select_passive.png"] forState:UIControlStateNormal];
}
[button setTitle:[NSString stringWithFormat:#"Object%d",i] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonEvent:) forControlEvents:UIControlEventAllEvents];
button.tag = 1000 + i ;
[self.view addSubview:button];
y += 60;
}
-(void)buttonEvent:(id)sender {
NSLog(#"new button clicked!!!");
}
You are adding buttons to uiimageview, which has interaction disabled.
Also, you don't have an array of buttons, because buttons is autoreleased, and you never add object into buttons array.