问题
Lords of Cocoa - I need assistance!
I'm coding up my first app (a game) and I'm trying to do the entire thing in the Core Frameworks and UIKit. My game involves a 5 x 8 board made from UIButtons that I've been creating manually (!). A massive PItA to update when I change the behaviour of one. I've tried using a mutable array and a UIButton generator but I'm terrible at this stuff still and I have been very unsuccesful in getting thing working.
The button stores it's state, a worth, an owner, and an origin. I currently have A,B,C,D,E reoresenting the columns and 1-8 for the rows. The buttons are 62x62 with a 1 pixel margin on either side of the grid and 2 pixel buffer and margin between the buttons.
Can someone help me get a nice little array generator from a class where I specify the tags, values etc... for each button and spit out the grid programatically?
Button Sample:
-(IBAction) buttonA1:(id)sender {
UIButton *theButton = (UIButton *)sender;
theButton.titleLabel.font = [UIFont fontWithName:@"Gotham Rounded" size:22];
NSString *Title = theButton.titleLabel.text;
if (tapA1 != 1) {
[theButton setAlpha:1.0];
tapSum++;
tapA1 = 1;
[theButton setTitle: @"A1" forState: UIControlStateNormal];
NSLog(@"Press recieved from %@:\n\nSum is %i.\n", Title, tapSum);
[theButton setBackgroundImage:[UIImage imageNamed:@"red-dot.png"] forState:UIControlStateNormal];
}
else if (tapA1 == 1)
{
[theButton setAlpha:0.3];
tapA1 = 0;
tapSum--;
NSLog(@"Press recieved from %@:\n\nSum is %i.\n", Title, tapSum);
}
Thanks in advance!
回答1:
Well You Can Create a GRID Like this:-
#define WIDTH 62
#define HEIGHT 62
#define PADDING 3
#define NUMBEROFBUTTONSINAROW 8
#define X 100
#define Y 100
#define TOTALBUTTONS 40
NSMutableArray *array = [[NSMutableArray alloc] init];
for(int i=0 ; i<TOTALBUTTONS;i++)
{
UIButton *btnClick = [UIButton buttonWithType:UIButtonTypeCustom];
[btnClick setImage:[UIImage imageNamed:@"ship.jpg"] forState:UIControlStateNormal];
[btnClick setFrame:CGRectMake(X+((WIDTH + PADDING) * (i%NUMBEROFBUTTONSINAROW)), Y + (HEIGHT + PADDING)*(i/NUMBEROFBUTTONSINAROW), WIDTH, HEIGHT)];
[btnClick addTarget:self action:@selector(btnTapped:) forControlEvents:UIControlEventTouchUpInside];
btnClick.tag=i + 1;
[self.view addSubview:btnClick];
[array addObject:btnClick];
}
and finally the button action :-
-(void)btnTapped:(id)sender
{
NSLog(@"Button Clicked %d",((UIButton *)sender).tag);
}
you can access the button by tag value . The array is not required. WELL BUT if you like , access it by array.
Alternatively You can create a class associating all the button customizations with it and store the class object in Array , only to access it later on.In , this case the button implementation will be in the class.
回答2:
Ok, for this solution I am assuming that you have a "TapxY" BOOL variable and "buttonxY:" selector for each button where x:[A,B,C,D,E] and Y:[1-8].
What you would want to do is make it so your button tags are 1000+n for each button (1000 just so that the tag is never 0. this can be anything as long as you keep track of it.)
This way the tags will be 1000,1001,...,1000+col*row-1 (which will be 1039 in a 5x8).
I am also assuming that tapxY (ex tapA1) will only ever be 0 or 1. What you will want to do is instead make an NSMutableArray of booleans (which can be stored as [NSNumber numberWithBool:boolVal]) which has col*row (40) elements that all start as [NSNumber numberWithBool:NO];
in your buttonAction:(id)sender method you can just have it do:
UIButton *theButton = (UIButton *)sender;
int buttonNum = theButton.tag-1000;
BOOL buttonTapped = [[tapped objectAtIndex:buttonNum] boolValue];
if (buttonTapped) { //Assuming tapped is your array of tapped buttons.
tapSum++;
//Set this button up however you want for the tapped state.
}
else {
tapSum--;
//Set this button up as not tapped
}
[tapped replaceObjectAtIndex:buttonNum withObject [NSNumber numberWithBool:!buttonTapped]]; //set this button as the opposite of what it just was.
Then when you create your buttons you just have to do:
int rows = 5;
int columns = 8;
for (int n=0;n<rows;n++) {
for (int m=0;m<columns;m++) {
CGRect frame = CGRectMake(1+64*n,1+64*m,62,62);
Button *button = [[UIButton alloc] initWithFrame:frame]; // or create a rounded rect and set its frame.
[button setTag:1000+n*columns+m]; //sets tag to a number 1000 to rows*columns-1
//Then do other setup for the button.
[button addTarget:self forSelector:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
}
Note: do not copy this code exactly as there are probably a few typos and it is untested
回答3:
Do you mean this?
#define kButtonSize 62
#define kMaxRows 6
#define kMaxColumns 4
#define kButtonSpacingWidth (([[UIScreen mainScreen].bounds.size.width - kMaxColumns * kButtonSize) / (kMaxColumns + 1))
#define kButtonSpacingHeight (([[UIScreen mainScreen].bounds.size.height - kMaxRows * kButtonSize) / (kMaxRows + 1))
- (UIButton *)buttonAtRow:(int)r column:(int)c
{
CGRect frm = CGRectMake(
kButtonSpacingWidth + c * (kButtonSize + kButtonSpacingWidth),
kButtonSpacingHeight + r * (kButtonSize + kButtonSpacingHeight),
kButtonSize,
kButtonSize
);
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.titleLabel.font = [UIFont fontWithName:@"FooBar-Bold" size:42.0];
btn.frame = frm;
[btn setBackgroundImage:[UIImage imageNamed:@"Baz.jpg"] forState:UIControlStateNormal];
return btn;
}
Just imagine how the buttons are placed, apply elementary school math like subtraction and division, and the rest is trivial.
回答4:
For loops to the rescue! You can make a grid with a little visual-spatial thinking:
-(void)generateSomeButtons {
int row = 0;
int col = 0;
for (int tag = 0; tag < 40; tag++)
UIButton *btn = //...
btn.tag = tag;
int buf = 1;
//no division by 0
if (tag == 0) {
buf = 2;
row = 0;
}
//Reset when it moves to the sixth element
else if (tag % 6 == 0) {
row = 0;
col++;
}
//Else buffer by 2 pixels
else {
buf = 2;
}
btn.frame = CGRectMake(buf + (row * 62), (col*62) + 2, 62, 62);
[self.view addSubview:btn];
row++;
}
}
It's just basic math here.
来源:https://stackoverflow.com/questions/15457820/objective-c-uibutton-grid-generation