In Objective-C, how can I make this code efficient? - objective-c

[self.menuBtn1 setImage:[UIImage imageNamed:#"menu1.png"] forState:UIControlStateNormal];
[self.menuBtn2 setImage:[UIImage imageNamed:#"menu2.png"] forState:UIControlStateNormal];
[self.menuBtn3 setImage:[UIImage imageNamed:#"menu3.png"] forState:UIControlStateNormal];
[self.menuBtn4 setImage:[UIImage imageNamed:#"menu4.png"] forState:UIControlStateNormal];
[self.menuBtn5 setImage:[UIImage imageNamed:#"menu5.png"] forState:UIControlStateNormal];
[self.menuBtn6 setImage:[UIImage imageNamed:#"menu6.png"] forState:UIControlStateNormal];
[self.menuBtn7 setImage:[UIImage imageNamed:#"menu7.png"] forState:UIControlStateNormal];
This Code is very inefficient. But I think it can be efficient with forsyntax. However I don't know how can I code self.menuBtn%d with for. In Objective-C, How can I code this?

This access the button properties dynamically so you don't need an array. This only works if the buttons have already been initialized (they are if they're IBOutlets)
NSString *imageName;
NSString *buttonName;
UIImage *image;
for (int i = 1; i < 8; i++) {
//#autoreleasepool {
imageName = [NSString stringWithFormat:#"menu%d", i];
buttonName = [NSString stringWithFormat:#"menuBtn%d", i];
image = [UIImage imageNamed:imageName];
UIButton *button = (UIButton *)[self valueForKey:buttonName];
if (button)
[button setImage:image forState:UIControlStateNormal];
/*
If you needed to scale this to say 1000 images, you can uncomment the first
and last line in the for-loop which will automatically release the variables
each iteration so the memory consumption doesn't spike.
*/
//}
}

One solution might be to set the tag of all your buttons to some value (e.g. 100 + button number), then to try:
for (UIButton *aButton in self.view.subviews)
{
if ((aButton.tag >= 100 and aButton.tag < 107))
[aButton setImage:[UIImage imageNamed:[NSString stringWithFormat:#"menu%d.png",aButton.tag]] forState:UIControlStateNormal];
}

First add the buttons to the array and the use for loop like this:
NSArray *array=[NSArray arrayWithObjects:menuBtn1,menuBtn2,menuBtn3,menuBtn4,menuBtn5,menuBtn6menuBtn7,nil];
int i=1;
for(UIButton *aButton in array){
[aButton setImage:[UIImage imageNamed:[NSString stringWithFormat:#"menu%d.png",i++]] forState:UIControlStateNormal];
}

NSString *menubutton;
NSMutableArray *imagearray = [[NSMutableArray alloc]initWithObjects:#"image1.png",#"image2.png",#"image3.png", nil];
for(int i=0; i<[imagearray count]; i++)
{
menubutton = [NSString stringWithFormat:#"menuBtn%d",i];
UIButton *button = (UIButton *)[self valueForKey:menubutton];
[button setImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#",[imagearray objectAtIndex:i]]] forState:UIControlStateNormal];
}

Related

buttons check the correct answer objective-c

I have one UIViewController and inside I have NSArray that I put my correct answer,and also I have 3 buttons, and 3 NSArray for their titles, I want to check if my buttons title was equal to the correct answer then goes to the correct page else goes to the wrong page
would you please help me to this implementation:
Thanks in advance!
Here is my code:
NSString *correctOne = #"test1";
NSString *correctTwo = #"test2";
NSString *correctThree = #"test3";
NSString *correctFour = #"test4";
NSString *correctFive = #"test5";
NSString *correctSix = #"test6";
NSString *correctSeven = #"test7";
NSString *correctEight = #"test8";
correctComments = [[NSArray alloc] initWithObjects: correctOne, correctTwo, correctThree,
correctFour, correctFive, correctSix, correctSeven, correctEight, nil];
int rand = arc4random()%8;
NSString *correct = [correctComments objectAtIndex:rand];
[test setTitle:(firstAnswer) forState:UIControlStateNormal];
[test setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
[test setTag:0];
[ansONE setTitle:(secondAnswer) forState:UIControlStateNormal];
[ansONE setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
[ansONE setTag:1];
[ansTWO setTitle:(threeAnswer) forState:UIControlStateNormal];
[ansTWO setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
[ansTWO setTag:2];
- (IBAction)suivant:(id)sender {
//MY Question is how should I check my button title and correctComments
}
- (IBAction)suivant:(id)sender {
UIButton *button = (UIButton *)sender;
int correctIndex = ...;
BOOL thisIsTheCorrectButton = (button.tag == correctIndex);
// Do whatever
}
At first you have to store correct answer from your code snippet to a property:
self.correctAnswer = correct;
Then do the comparision of those strings:
- (IBAction)suivant:(UIButton *)sender {
// You wanted to check for title:
if ([sender.currentTitle isEqualToString:self.correctAnswer]) {
// Correct...
}
else {
// Wrong...
}
}

How to have a UIButton image change when a button is touched

I'm trying to have the UIButton image change when a button is touched. Currently I it changes but only on the highlighted state change. I would like it to change and stay there. I tried UIControlStateSelected for the state change but no luck.
thanks for the help
here's my code:
// Create buttons for the sliding category menu.
NSMutableArray* buttonArray = [NSMutableArray array];
NSArray * myImages = [NSArray arrayWithObjects:#"category-cafe-unsel.png", #"category-food-unsel.png", #"category-clothing-unsel.png", #"category-health-unsel.png", #"category-tech-unsel_phone.png" , #"category-tech2-unsel.png", #"catefory-theatre-unsel.png", #"category-travel-unsel.png", nil];
NSArray * myImagesSel = [NSArray arrayWithObjects:#"category-cafe-sel.png", #"category-food-sel.png", #"category-clothing-sel.png", #"category-health-sel.png", #"category-tech-sel_phone.png" , #"category-tech2-sel.png", #"catefory-theatre-sel.png", #"category-travel-sel.png", nil];
// only create the amount of buttons based on the image array count
for(int i = 0;i < [myImages count]; i++)
{
// Custom UIButton
btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(0.0f, 20.0f, 52.0f, 52.0f)];
[btn setTitle:[NSString stringWithFormat:#"Button %d", i] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:[myImages objectAtIndex:i]] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:[myImagesSel objectAtIndex:i]] forState:UIControlStateHighlighted];
NSLog(#"The button title is %# ", btn.titleLabel.text);
[btn addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[buttonArray addObject:btn];
In your IBAction method add the following lines:
- (IBAction)change:(id)sender
{
UIButton *button = (UIButton *)sender;
int tagOfButton = button.tag - 1;
[button setImage:[UIImage imageNamed:[myImagesSel objectAtIndex:tagOfButton]] forState:UIControlStateNormal];
}
Add a single line to your for loop like:
for(int i = 0;i < [myImages count]; i++)
{
// other stuffs
btn.tag = i+1;
}
EDIT:
If you need to undone the previous selection when other button is clicked:
write this loop inside your IBAction method.
for(int i = 0;i < [myImages count]; i++)
{
UIButton *but = (UIButton *)[buttonArray objectAtIndex:i];
if(but != button)
{
[btn setImage:[UIImage imageNamed:[myImages objectAtIndex:i]] forState:UIControlStateNormal];
}
}
Or simply store the previous button tag to a variable.
And use it to change undone the image change.
[btn setTitle:#"I'm not selected" forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:[myImages objectAtIndex:i]] forState:UIControlStateNormal];
[btn setTitle:#"I'm selected" forState:UIControlStateSelected];
[btn setImage:[UIImage imageNamed:[myImagesSel objectAtIndex:i]] forState:UIControlStateSelected];
[btn addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
-(IBAction)buttonPressed:(id)sender {
btn.selected = !btn.selected;
}

specific title for each button in UIScrollView

I have an UIWebView page with one UIScrollView, inside of my UIScrollView I have UIImage and buttons
I want to set specific title for each button from my xml file, Would you please give me some hint for implementing this?
rightnow I can get the first name from xml but it"s set for all
my scrollView with Button and images:
const NSUInteger kNumImages = 5;
scrollView1.pagingEnabled = YES;
// load all the images
NSUInteger i;
for (i = 1; i<= kNumImages; i++)
{
NSString *imageName = [NSString stringWithFormat:#"image%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.userInteractionEnabled = YES;
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i;
[scrollView1 addSubview:imageView];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
appDelegate = (testAppDelegate *)[[UIApplication sharedApplication] delegate];
Presentation1Name *aSlide = [appDelegate.books objectAtIndex:0];
NSLog(#" %#", aSlide.slideLabel );
[btn setTitle:[NSString stringWithString:aSlide.slideLabel]
forState:UIControlStateNormal];
btn.frame = rect;
[btn setTag:i];
[btn addTarget:self action:#selector(buttonClick:)
forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:btn];
}
[self layoutScrollImages];
}
for adding title for all button I'm using code
[btn setTitle:[NSString stringWithString:aSlide.slideLabel]
forState:UIControlStateNormal];
but for each button I want to have specific title from xml file
Thanks in advance!
Here is my xml file:
<Presentation label="presentation1">
<slides>
<slide index="0" label="slide1" identifier="Slide1Name" />
<slide index="1" label="something" identifier="Slide2Name" />
</slides>
</Presentation>
Edit:
When I add Presentation1Name *aSlide = [appDelegate.books objectAtIndex:0]; objectAtIndex to i I will get this error
when I add objectAtIndex: i
process terminated * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' -[NSPlaceholderString initWithString:]: nil argument'
** First throw call stack:
(0x1c95012 0x10d2e7e 0x1c94deb 0xae97f5 0xae9774 0x3d64 0x4723 0x10e6705 0x1d920 0x1d8b8 0xde671 0xdebcf 0xddd38 0x4d33f 0x4d552 0x2b3aa 0x1ccf8 0x1bf0df9 0x1bf0ad0 0x1c0abf5 0x1c0a962 0x1c3bbb6 0x1c3af44 0x1c3ae1b 0x1bef7e3 0x1bef668 0x1a65c 0x295d 0x2885 0x1)
libc++abi.dylib: terminate called throwing an exception
(lldb)
and it"s because of
-[NSPlaceholderString initWithString:]: nil argument'
after that I change 5 t0 2 since I have just 2 label in my xml file
const NSUInteger kNumImages= 2;
and also change for (i = 1; i<= kNumImages; i++) to
for (i = 0; i> kNumImages; i++)
but still it"not working correctly
My question is How can I do this
appDelegate.books count should be equal to kNumImages
[btn setTitle:[NSString stringWithFormat:#"MyButton %d", i] forState:UIControlStateNormal];
Store all button names in NSMutableArray and then later use it
For example like this:
NSMutableArray *arrNames = [NSMutableArray alloc]initWithObjects:#"Dog",#"Cat",......,nil]; //fill your array
[btn setTitle:[arrNames objectAtIndex:i] forState:UIControlStateNormal];
Second option is to use #Andrey Chernukha justed in his answer

how to add background color to UIbuttons crested by using for loop based on frame sizes?

I have created 5 buttons using for loop based on incrementing y axis value in CGRectMake. But how can i change the background color of button when i clicked each button?and also title AND having alertview for each button??pls suggest me answer..
//array taken for button titles
NSArray *array1=[NSArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5", nil];
int k=0;
for(int i=50;i<=350;i=i+70)
{
button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame=CGRectMake(30,i,35,40);
[button addTarget:self action:#selector(buttonclicked:) forControlEvents:UIControlEventTouchUpInside];
if (k<[array1 count])
{
[button setTitle:[array1 objectAtIndex:k] forState:UIControlStateNormal];
}
k++;
[self.view addSubview:button];
}
Try this
-(void) buttonClicked:(id) sender
{
UIButton * button = (UIButton*) sender;
button.backgroundColor = [UIColor yellowcolor];
[button setTitle:#"Hello" forState:UIControlStateNormal];
}
Set the tag for each button and when it's call buttonclicked: is called, then use it's tag rod decide which background color to set it to::
int temptag;
temptag = 0;
for(int i=50;i<=350;i=i+70)
{
button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame=CGRectMake(30,i,35,40);
[button addTarget:self action:#selector(buttonclicked:) forControlEvents:UIControlEventTouchUpInside];
button.tag = temptag;
if (k<[array1 count])
{
  [button setTitle:[array1 objectAtIndex:k] forState:UIControlStateNormal];
  }
k++;  
temptag++;
[self.view addSubview:button];
}
-(void)buttonclicked:(id)sender
{
UIButton *btn = (UIButton *)sender;
switch (btn.tag) {
case 0:
btn.backgroundColor = [UIColor redColor];
break;
case 1:
btn.backgroundColor = [UIColor grayColor];
break;
case ...:
....
default:
break;
}
}

Trouble with "viewWithTag"

oldTag button is not changing back to white ??
What am I missing?
thx
-(void) myCharValue: (UIButton*)btn
{
[btn setBackgroundColor:[UIColor redColor]]; //current tag_button pressed
UIButton *btnTemp;
btnTemp = (UIButton*)[btnChar viewWithTag:oldTag];
[btnTemp setBackgroundColor:[UIColor whiteColor]]; // <--- oldTag button is not changing back to white ??
oldTag = btn.tag;
}
//setup
for (int i=0; i<16; i++) {
for (int j=0; j<16; j++) {
btnChar = [UIButton buttonWithType:UIButtonTypeCustom ];
[btnChar setFrame:CGRectMake(j*40+1, i*40+1, 38, 38)];
[btnChar setBackgroundColor:[UIColor whiteColor]];
[btnChar setTitle:[NSString stringWithFormat:#"%c", k] forState:UIControlStateNormal ];
[btnChar setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btnChar addTarget:self action:#selector(myCharValue:) forControlEvents:UIControlEventTouchUpInside];
[btnChar setTag:k];
[svDisplay addSubview:btnChar];
k++;
}
}
I just want to add that the default value of tag property is 0, so if you start your loop with 0, first button will technically not be tagged. Later when you request a viewWithTag: 0 from svDisplay (chech #jrtc27's answer), you will get a first view in that [svDisplay subviews] array.
Your buttons are subviews of svDisplay, not btnChar, so the line btnTemp = (UIButton*)[btnChar viewWithTag:oldTag]; should be btnTemp = (UIButton*)[svDisplay viewWithTag:oldTag];.