Reputation: 23
I have spent a few hours trying to accomplish what I thought would be a simple task. I am trying to generate 10 non-rotated square buttons on my iphone screen programmatically without them overlapping. Whenever I get what I think is the correct code, the app just hangs. Heres what I am trying to do so far:
First I have a while loop that keeps attempting to generate buttons until there are 10 (hence the hang). This loop calculates a random width and height to generate the button on.
I then attempt to check if the button would cause overlap with any button currently placed on screen (note: this is in intervals for efficiency, but has been tested without). If the button may overlap, I "continue;", but if not then I generate the button.
After generate the button I put the coordinates where other buttons should not be placed into their specific, axis based arrays to check in the loops ahead.
This is my code:
- (void)addNumbers{
int width = [[UIScreen mainScreen] bounds].size.width - 70;
int height = [[UIScreen mainScreen] bounds].size.height - 110;
NSMutableArray* xarray = [[NSMutableArray alloc] init];
NSMutableArray* yarray = [[NSMutableArray alloc] init];
int buttons = 0;
while(buttons < 10) {
int x = 10*floor(10+arc4random_uniform(width)/10);
int y = 10*floor(50+arc4random_uniform(height)/10);
NSLog(@"The coords are: %i, %i",x,y);
if([xarray containsObject:[NSNumber numberWithInt:x]] && [yarray containsObject:[NSNumber numberWithInt:y]]){
NSLog(@"Triggered");
continue;
}
[self generateButton:x :y :buttons];
buttons++;
for(int i = 0; i < 6; i++){
[xarray addObject:[NSNumber numberWithInt:(x+i*10)]];
[yarray addObject:[NSNumber numberWithInt:(y+i*10)]];
[xarray addObject:[NSNumber numberWithInt:(x-i*10)]];
[yarray addObject:[NSNumber numberWithInt:(y-i*10)]];
}
}
}
- (void)generateButton:(int)x :(int)y :(int)num{
UIButton * btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(x, y, 60, 60);
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor whiteColor]];
btn.titleLabel.font = [UIFont fontWithName:@"Avenir" size:40.0f];
[btn setTitle:[NSString stringWithFormat:@"%d",num] forState:UIControlStateNormal];
[self.view addSubview:btn];
[self.squareArray addObject:btn];
}
Please help me :'(
Also I am new to Objective-C (probably obvious) so feel free to comment on any way I can improve my code or efficiency.
Upvotes: 2
Views: 1046
Reputation: 39091
I'll give you what I would've done.
-(BOOL)isButtonOverlapping:(NSArray *)array button:(UIButton *)btn {
for (UIButton *btn_ in [array copy]) {
if (CGRectIntersectsRect(btn_, btn)) return YES;
}
return NO;
}
-(void)addNumbers {
int width = [[UIScreen mainScreen] bounds].size.width - 70;
int height = [[UIScreen mainScreen] bounds].size.height - 110;
NSMutableArray *buttonsArray = [NSMutableArray new];
for (short button = 0; button < 10; button++) {
UIButton *btn = [self generateButton:x :y :button];
do {
btn.center = CGPointMake(rand() % width, rand() % height);
} while ([self isButtonOverlapping:buttonsArray button:btn]);
[buttonsArray addObject:btn];
}
}
-(UIButton *)generateButton:(int)x :(int)y :(int)num {
UIButton * btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(x, y, 60, 60);
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor whiteColor]];
btn.titleLabel.font = [UIFont fontWithName:@"Avenir" size:40.0f];
[btn setTitle:[NSString stringWithFormat:@"%d",num] forState:UIControlStateNormal];
[self.view addSubview:btn];
[self.squareArray addObject:btn];
return btn;
}
Upvotes: 2