Thursday, May 20, 2010

IPAD Math: dynamic button display

I found that having the math buttons at the bottom of the screen for the proper choice was a poor UI choice.  It caused your eyes to travel from the problem to the buttons and back, slowing down the process.  I made a preliminary UI overlay that allows buttons to be dynamically displayed. This is not a final solution, it takes up too much screen real-estate however it was a good experiment with dynamic view overlays.

The only reason I'm showing this stage, is so that I can discuss the refactoring that will occur to create cleaner, more modular code.

I display a set of buttons around the problem being currently displayed. I made the buttons the same size as the problem, however that didn't allow enough choices, and takes up too much real estate.
In MathProblem I added a method that returns a list of possible choices for the math problem.  In this case it only returns 8 choices, which is based on the display method I'm using.   
- (NSMutableArray *)calculateChoices;

- (NSMutableArray *)calculateChoices
{
NSMutableArray *set=[[NSMutableArray alloc]init];
for (int i=0;i<9;i++)
{
if (i==correctResult)
continue;
[set addObject:[NSNumber numberWithInt:i]];
}
NSNumber *correctResultO=[NSNumber numberWithInt:correctResult];
    NSMutableSet *returnValues=[[NSMutableSet alloc]init];
[returnValues addObject:correctResultO];
for (int i=0;i<7;i++)
{
int randomalue=arc4random()%[set count];
NSNumber * value=(NSNumber *)[set objectAtIndex:randomalue];
[set removeObject:value];
[returnValues addObject:value];
}
[set release];
return [returnValues autorelease];
}

Next I refactored the MathDrillViewController to have some additional properties, and methods to handle displaying a set of selections:
@property (nonatomic,retain) UIView *choiceView;

and I modified the set problem choice to display the dialog.


- (void) setProblemNumber:(int) problemNumber
{
NSLog(@"Choosing problem %d",problemNumber);
if ((currentProblem>=0) && (currentProblem<=[currentProblems count]))
{
MathProblem *oldProblem=(MathProblem*)[currentProblems objectAtIndex:currentProblem];
if (choiceView!=nil)
{
[choiceView removeFromSuperview];
self.choiceView=nil;
}

oldProblem.view.alpha=0.5;
}
currentProblem=problemNumber;
MathProblem *problem=(MathProblem*)[currentProblems objectAtIndex:currentProblem];
problem.view.alpha=1;
int width=problem.view.frame.size.width;
int height=problem.view.frame.size.height;
self.choiceView =[[UIView alloc] initWithFrame:CGRectMake(problem.view.frame.origin.x-width, problem.view.frame.origin.y-height,
  problem.view.frame.size.width*3, problem.view.frame.size.height*3)];
self.choiceView.center=problem.view.center;
[self.displayArea addSubview:choiceView];

choiceView.backgroundColor=[UIColor colorWithRed:0 green:0 blue:0 alpha:0];
NSMutableArray *choices=problem.resultChoices;
int row=0;
int column=0;
for (NSNumber *value in choices)
{
if ((row==1) &&(column==1))
column++;
UIButton *button=[[UIButton alloc]init] ;
button.tag=[value intValue]; 
button.frame=CGRectMake(column*width,height*row,width,height);
button.backgroundColor=[UIColor redColor];
button.userInteractionEnabled=true;
[button setTitle:[value stringValue] forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonChosen:) forControlEvents:UIControlEventTouchUpInside];
[self.choiceView addSubview:button];
column++;
if (column>=3)
{
column=0;
row++;
}
}

}

Originally I had the choiceView belong to the math problem view, but when I did that I didn't get button presses, and the alpha was picked up from the problem view (causing strange display  results).

Note the line:

choiceView.backgroundColor=[UIColor colorWithRed:0 green:0 blue:0 alpha:0];
This set the background to be transparent, so that only the buttons are displayed.


No comments:

Post a Comment