Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 11-23-2010, 10:46 AM   #1 (permalink)
Creator of From A to B
 
fudgie_no1's Avatar
 
Join Date: Nov 2010
Location: Wales
Posts: 45
fudgie_no1 is on a distinguished road
Unhappy Reference controls dynamically

Hi everyone, a very useful forum here with some priceless advice! I've scoured around for most of the day but can't find an answer to the following question.

What I'd like to do is to reference a control dynamically.

For example, Let's say I have:
3 buttons called Button1, Button2 and Button3
1 NSInteger called MyButtonNumber

I have a calculation that determines the button I want to use and I store this to an NSInteger (MyButtonNumber = 2, I'd like to be able to do the following;

[(@"Button" & MyButtonNumber) setBackgroundImage:[UIImage imageNamed:@"test.png"] forState:UIControlStateNormal];

Any help would be greatly appreciated as I really don't want to code every possibility. This would dramatically reduce the amount of code in my app.

Thanks for you time.
fudgie_no1 is offline   Reply With Quote
Old 11-23-2010, 10:55 AM   #2 (permalink)
Reading the Documentation
 
baja_yu's Avatar
 
Join Date: Sep 2010
Location: 45.255019,19.844908
Posts: 5,414
baja_yu has a spectacular aura about
Default

You could use switch statement on the number and based on that alter the appropriate button. Also, but I'm not sure if it would work, add the buttons to an array and access them by index (using the number as index, starting from 0)
baja_yu is offline   Reply With Quote
Old 11-23-2010, 11:44 AM   #3 (permalink)
Creator of From A to B
 
fudgie_no1's Avatar
 
Join Date: Nov 2010
Location: Wales
Posts: 45
fudgie_no1 is on a distinguished road
Default

Quote:
Originally Posted by baja_yu View Post
You could use switch statement on the number and based on that alter the appropriate button. Also, but I'm not sure if it would work, add the buttons to an array and access them by index (using the number as index, starting from 0)
Thanks very much for your quick reply! I kind of understand what you mean but I don't think it applies to what I'm trying to do. Say I had 5 columns and 5 rows of UIButtons (25 buttons in total) I would declare them and link to them in IB as follows:

C1R1 C2R1 C3R1 C4R1 C5R1
C1R2 C2R2 C3R2 C4R2 C5R2
C1R3 C2R3 C3R3 C4R3 C5R3
C1R4 C2R4 C3R4 C4R4 C5R4
C1R5 C2R5 C3R5 C4R5 C5R5

My calculation will work out what button I'm going to next by calculation the column number and row number. So I'd like to be able to do something like:

TheButtonToUse = @"C" & MyColumnResult & @"R" & MyRowResult

[TheButtonToUse setBackgroundImage:[UIImage imageNamed:@"test.png"] forState:UIControlStateNormal];

Any advice and some sample code would be greatly appreciated. Thanks
fudgie_no1 is offline   Reply With Quote
Old 11-23-2010, 01:40 PM   #4 (permalink)
Reading the Documentation
 
baja_yu's Avatar
 
Join Date: Sep 2010
Location: 45.255019,19.844908
Posts: 5,414
baja_yu has a spectacular aura about
Default

Code:
	NSMutableArray *buttonArray = [[NSMutableArray alloc] init];
	for (int i=0; i<5; i++) {
		NSMutableArray *insideArray = [[NSMutableArray alloc] init];
		for (int j=0; j<5; j++) {
			UIButton *aButton = [[UIButton alloc] init];
			[aButton setTitle:[NSString stringWithFormat:@"C%dR%d", j, i] forState:UIControlStateNormal];
			[insideArray addObject:aButton];
			[aButton release];
		}
		[buttonArray addObject:insideArray];
		[insideArray release];
	}
	
	UIButton *buttonAtColumn2Row4 = (UIButton *)[(NSMutableArray *)[buttonArray objectAtIndex:4] objectAtIndex:2]
Didn't test it, but should do what you want.
baja_yu is offline   Reply With Quote
Old 11-23-2010, 02:48 PM   #5 (permalink)
Creator of From A to B
 
fudgie_no1's Avatar
 
Join Date: Nov 2010
Location: Wales
Posts: 45
fudgie_no1 is on a distinguished road
Default

Quote:
Originally Posted by baja_yu View Post
Code:
	NSMutableArray *buttonArray = [[NSMutableArray alloc] init];
	for (int i=0; i<5; i++) {
		NSMutableArray *insideArray = [[NSMutableArray alloc] init];
		for (int j=0; j<5; j++) {
			UIButton *aButton = [[UIButton alloc] init];
			[aButton setTitle:[NSString stringWithFormat:@"C%dR%d", j, i] forState:UIControlStateNormal];
			[insideArray addObject:aButton];
			[aButton release];
		}
		[buttonArray addObject:insideArray];
		[insideArray release];
	}
	
	UIButton *buttonAtColumn2Row4 = (UIButton *)[(NSMutableArray *)[buttonArray objectAtIndex:4] objectAtIndex:2]
Didn't test it, but should do what you want.
Wow! That's some unbelievable tekkers! thanks again for your help, I still don't think this is what I want though. I think my explanation might have been too long winded. So how about this....

Instead of writing:

[C1R1 setBackgroundImage:[UIImage imageNamed:@"test.png"] forState:UIControlStateNormal];

I want to write:
ColumnNumber = 1;
RowNumber = 1;
TheButtonToUse = @"C" & ColumnNumber & @"R" & RowNumber

[TheButtonToUse setBackgroundImage:[UIImage imageNamed:@"test.png"] forState:UIControlStateNormal];

I just need to know how to reference a UIButton using variables stored in NSIntegers?? I'm really sorry to be a pain but this would save me loads of time with my code and would ensure faster run times.

Thanks again for your time, much appreciated!
fudgie_no1 is offline   Reply With Quote
Old 11-23-2010, 02:57 PM   #6 (permalink)
Reading the Documentation
 
baja_yu's Avatar
 
Join Date: Sep 2010
Location: 45.255019,19.844908
Posts: 5,414
baja_yu has a spectacular aura about
Default

With the my code above do

Code:
columnNumber = 1;
rowNumber = 1;
theButtonToUse = (UIButton *)[(NSMutableArray *)[buttonArray objectAtIndex:rowNumber] objectAtIndex:columnNumber]
//then do what you want to theButtonToUse
EDIT: Also, just note that NSMutableArrays are zero based so your button indexes (column/row numbers) would go from 0 to 4 instead of 1 to 5.

Last edited by baja_yu; 11-23-2010 at 02:59 PM.
baja_yu is offline   Reply With Quote
Old 11-23-2010, 03:43 PM   #7 (permalink)
Creator of From A to B
 
fudgie_no1's Avatar
 
Join Date: Nov 2010
Location: Wales
Posts: 45
fudgie_no1 is on a distinguished road
Default

Quote:
Originally Posted by baja_yu View Post
With the my code above do

Code:
columnNumber = 1;
rowNumber = 1;
theButtonToUse = (UIButton *)[(NSMutableArray *)[buttonArray objectAtIndex:rowNumber] objectAtIndex:columnNumber]
//then do what you want to theButtonToUse
EDIT: Also, just note that NSMutableArrays are zero based so your button indexes (column/row numbers) would go from 0 to 4 instead of 1 to 5.
Thanks again Baja_Yu. After a bit of testing I came to realise the issue with the 0 and changed them accordingly. However, it still isn't working.

In this example I have 3 columns and two rows.

.h has the following:

#import <UIKit/UIKit.h>

@interface Button_TestViewController : UIViewController {
IBOutlet UIButton * Button1;
IBOutlet UIButton * Button2;

IBOutlet UIButton * C0R0;
IBOutlet UIButton * C1R0;
IBOutlet UIButton * C2R0;
IBOutlet UIButton * C0R1;
IBOutlet UIButton * C1R1;
IBOutlet UIButton * C2R1;

IBOutlet UIButton * TellMeImage;

NSString * ItemISelected;

UIButton * MyButtonToCheck;
}

-(IBAction) ButtonPushedid)sender;
-(IBAction) ItemSelectedid)sender;
-(IBAction) MessageMeImage;

@end

This is my function in .m

-(IBAction) MessageMeImage{

NSMutableArray *buttonArray = [[NSMutableArray alloc] init];
for (int i=0; i<2; i++) {
NSMutableArray *insideArray = [[NSMutableArray alloc] init];
for (int j=0; j<3; j++) {
UIButton *aButton = [[UIButton alloc] init];
[aButton setTitle:[NSString stringWithFormat:@"C%dR%d", j, i] forState:UIControlStateNormal];
NSLog([NSString stringWithFormat:@"C%dR%d", j, i]);

[insideArray addObject:aButton];
[aButton release];
}
[buttonArray addObject:insideArray];
[insideArray release];
}

MyButtonToCheck = (UIButton *)[(NSMutableArray *)[buttonArray objectAtIndex:1] objectAtIndex:1];
NSLog([NSString stringWithFormat:@"%d", C1R1]);
NSLog([NSString stringWithFormat:@"%d", MyButtonToCheck]);

[MyButtonToCheck setImage:[UIImage imageNamed:@"two.PNG"] forState:UIControlStateNormal];
}

NSLog comes out as follows:

2010-11-24 00:36:38.756 Button Test[1418:207] C0R0
2010-11-24 00:36:38.758 Button Test[1418:207] C1R0
2010-11-24 00:36:38.759 Button Test[1418:207] C2R0
2010-11-24 00:36:38.760 Button Test[1418:207] C0R1
2010-11-24 00:36:38.761 Button Test[1418:207] C1R1
2010-11-24 00:36:38.763 Button Test[1418:207] C2R1
2010-11-24 00:36:38.764 Button Test[1418:207] 99990976
2010-11-24 00:36:38.767 Button Test[1418:207] 100063968
2010-11-24 00:36:38.996 Button Test[1418:207] C0R0
2010-11-24 00:36:38.998 Button Test[1418:207] C1R0
2010-11-24 00:36:38.999 Button Test[1418:207] C2R0
2010-11-24 00:36:39.000 Button Test[1418:207] C0R1
2010-11-24 00:36:39.002 Button Test[1418:207] C1R1
2010-11-24 00:36:39.003 Button Test[1418:207] C2R1
2010-11-24 00:36:39.004 Button Test[1418:207] 99990976
2010-11-24 00:36:39.007 Button Test[1418:207] 100066704
2010-11-24 00:36:39.197 Button Test[1418:207] C0R0
2010-11-24 00:36:39.198 Button Test[1418:207] C1R0
2010-11-24 00:36:39.199 Button Test[1418:207] C2R0
2010-11-24 00:36:39.201 Button Test[1418:207] C0R1
2010-11-24 00:36:39.202 Button Test[1418:207] C1R1
2010-11-24 00:36:39.203 Button Test[1418:207] C2R1
2010-11-24 00:36:39.204 Button Test[1418:207] 99990976
2010-11-24 00:36:39.207 Button Test[1418:207] 100069392
2010-11-24 00:36:39.433 Button Test[1418:207] C0R0
2010-11-24 00:36:39.435 Button Test[1418:207] C1R0
2010-11-24 00:36:39.436 Button Test[1418:207] C2R0
2010-11-24 00:36:39.437 Button Test[1418:207] C0R1
2010-11-24 00:36:39.439 Button Test[1418:207] C1R1
2010-11-24 00:36:39.440 Button Test[1418:207] C2R1
2010-11-24 00:36:39.442 Button Test[1418:207] 99990976
2010-11-24 00:36:39.443 Button Test[1418:207] 100072128
2010-11-24 00:36:43.210 Button Test[1418:207] C0R0
2010-11-24 00:36:43.212 Button Test[1418:207] C1R0
2010-11-24 00:36:43.213 Button Test[1418:207] C2R0
2010-11-24 00:36:43.214 Button Test[1418:207] C0R1
2010-11-24 00:36:43.215 Button Test[1418:207] C1R1
2010-11-24 00:36:43.216 Button Test[1418:207] C2R1
2010-11-24 00:36:43.217 Button Test[1418:207] 99990976
2010-11-24 00:36:43.220 Button Test[1418:207] 100074864

It seems as though the permanent name (C1R1) returns the same value every time but the function we're trying to create just goes up and up??

Needless to say, the image doesn't change as it should. Any ideas? Thank you so much for you time!
fudgie_no1 is offline   Reply With Quote
Old 11-24-2010, 02:22 AM   #8 (permalink)
Reading the Documentation
 
baja_yu's Avatar
 
Join Date: Sep 2010
Location: 45.255019,19.844908
Posts: 5,414
baja_yu has a spectacular aura about
Default

First problem, you're populating the buttonArray on each MessageMe IBAction. Instead move this block to viewDidLoad

Code:
NSMutableArray *buttonArray = [[NSMutableArray alloc] init];
for (int i=0; i<2; i++) {
   NSMutableArray *insideArray = [[NSMutableArray alloc] init];
   for (int j=0; j<3; j++) {
      UIButton *aButton = [[UIButton alloc] init];
      [aButton setTitle:[NSString stringWithFormat:@"C%dR%d", j, i] forState:UIControlStateNormal];
      NSLog([NSString stringWithFormat:@"C%dR%d", j, i]);

      [insideArray addObject:aButton];
      [aButton release];
   }
   [buttonArray addObject:insideArray];
   [insideArray release];
}
The second problem is that you have IBOutlets declared in the header but you are populating the array with new buttons, so they are not connected.

Check this code with corrections:

Code:
@interface Button_TestViewController : UIViewController {
	IBOutlet UIButton * Button1;
	IBOutlet UIButton * Button2;
	
	IBOutlet UIButton * C0R0;
	IBOutlet UIButton * C1R0;
	IBOutlet UIButton * C2R0;
	IBOutlet UIButton * C0R1;
	IBOutlet UIButton * C1R1;
	IBOutlet UIButton * C2R1;
	
	IBOutlet UIButton * tellMeImage;
	
	NSString *itemISelected;
	
	UIButton *myButtonToCheck;
	
	NSMutableArray *buttonArray;
}

-(IBAction) ButtonPushedid)sender;
-(IBAction) ItemSelectedid)sender;
-(IBAction) MessageMeImage;

@end

//This is my function in .m

-(IBAction) MessageMeImage{
	myButtonToCheck = (UIButton *)[(NSMutableArray *)[[self buttonArray] objectAtIndex:1] objectAtIndex:1];
	NSLog([C1R1 title]);
	NSLog([myButtonToCheck title]);
	
	[myButtonToCheck setImage:[UIImage imageNamed:@"two.PNG"] forState:UIControlStateNormal];
}

- (void)viewDidLoad {
	[super viewDidLoad];
	
	NSMutableArray *newButtonArray = [[NSMutableArray alloc] init];
	
	//add row one (index 0)
	NSMutableArray *insideArray = [[NSMutableArray alloc] init];
	[insideArray addObject:C0R0];
	[insideArray addObject:C1R0];
	[insideArray addObject:C2R0];
	[buttonArray addObject:insideArray];
	[insideArray release];
	
	NSMutableArray *insideArray = [[NSMutableArray alloc] init];
	[insideArray addObject:C0R1];
	[insideArray addObject:C1R1];
	[insideArray addObject:C2R1];
	[buttonArray addObject:insideArray];
	[insideArray release];
	
	[self setButtonArray:newButtonArray];
	[newButtonArray release];
}
baja_yu is offline   Reply With Quote
Old 11-24-2010, 03:47 AM   #9 (permalink)
Creator of From A to B
 
fudgie_no1's Avatar
 
Join Date: Nov 2010
Location: Wales
Posts: 45
fudgie_no1 is on a distinguished road
Default

Baja_yu, I take my hat off to you for taking your time to help me. I think you've hit the nail on the head and we're on the right path. However, when I try to build and run the app refuses to load. It doesn't like the NSMutablearrays code at all. Thanks for your help but I think I'm just going to hard code it all as I've wasted enough of both of our times so far. Thanks

Last edited by fudgie_no1; 11-24-2010 at 03:57 AM.
fudgie_no1 is offline   Reply With Quote
Old 11-24-2010, 05:10 AM   #10 (permalink)
Reading the Documentation
 
baja_yu's Avatar
 
Join Date: Sep 2010
Location: 45.255019,19.844908
Posts: 5,414
baja_yu has a spectacular aura about
Default

If you're still up for giving it a try we can do some debugging. I think I made a mistake there in the code above in viewDidLoad, instead of these lines like

[insideArray addObject:C0R0];

use [self XXX], like

[insideArray addObject:[self C0R0]];

You may also want to add @property declarations in the header for all the buttons, ie

@property (nonatomic, retain) IBOutlet UIButton *C0R0;

and synthesize them in the implementation with

@synthesize C0R0;
baja_yu is offline   Reply With Quote
Old 11-25-2010, 07:24 AM   #11 (permalink)
Creator of From A to B
 
fudgie_no1's Avatar
 
Join Date: Nov 2010
Location: Wales
Posts: 45
fudgie_no1 is on a distinguished road
Default

Quote:
Originally Posted by baja_yu View Post
If you're still up for giving it a try we can do some debugging. I think I made a mistake there in the code above in viewDidLoad, instead of these lines like

[insideArray addObject:C0R0];

use [self XXX], like

[insideArray addObject:[self C0R0]];

You may also want to add @property declarations in the header for all the buttons, ie

@property (nonatomic, retain) IBOutlet UIButton *C0R0;

and synthesize them in the implementation with

@synthesize C0R0;
Thanks again for your help, you pointed me in the right direction with the arrays. What I've done now is one big array and I use a formula to calculate the index of the button I want (works great!).

One query with NSArray's though... If I use any string as the first entry (eg @"FirstEntry") then the array works perfectly. If the first entry is a button (eg C1R1) then it doesn't work. Does the first entry of an array always need to be a string??

Using the array turned 542 lines of code into 2!!
fudgie_no1 is offline   Reply With Quote
Old 11-25-2010, 07:53 AM   #12 (permalink)
Reading the Documentation
 
baja_yu's Avatar
 
Join Date: Sep 2010
Location: 45.255019,19.844908
Posts: 5,414
baja_yu has a spectacular aura about
Default

I'm glad it's working out for you. I don't think there's a limitation on object type. What do you mean by 'doesn't work', does it give you an error? Could you post some code?

Also, to be on the same page with terminology, note that there's a difference between NSArray and NSMutableArray (first is static, the other is dynamic).
baja_yu is offline   Reply With Quote
Reply

Bookmarks

Tags
controls, dynamically, nsinteger, reference, uibutton

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 374
5 members and 369 guests
Kirkout, MarkC, Sami Gh, SamorodovAlex, VinceYuan
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,664
Threads: 94,120
Posts: 402,898
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Leslie80
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 02:45 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0