Thursday, October 14, 2010

Stupid UIAlertView Tricks Part Deux

Note: This blog is deprecated. @synthesize zach has moved to a new home, at zpasternack.org. This blog entry can be found on the new blog here. Please update your links.

Another Stackoverflow question has prompted me to yet again revisit the issue of putting random views into a UIAlertView.

If you missed my previous installments, check out UIAlertView with UITextField (which is actually moderately useful at times), and UIAlertView with UIWebView, which is pretty much not good for anything except guffaws.

In this installment, we'll jam a UITableView in there, and even throw in some UISwitch controls for good measure.

Note: never do this.  Though I don't believe it's a direct violation of the Almighty Apple Book Of Holiness Human Interface Guidelines, it would surely make most iPhone UI Geeks cringe.  I'm not a UI hardliner, but I wouldn't do this in one of my apps.  Neither Fat Apps, nor myself are responsible for any App Store rejections, loss of life, loss of limb, or loss of credibility that may result from using this code in an actual app.  This is for fun.

Now then.  Much like putting any other random view in an alert view, there's really not that much work to do beyond what you'd normally do if you were making such a view without the alert view.  In the case of a UITableView, you need to have a class which implements UITableViewDataSource.  Create the cells in tableView:cellForRowAtIndexPath:, and add your controls as the accessoryView, like so:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* const SwitchCellID = @"SwitchCell";
UITableViewCell* aCell = [tableView dequeueReusableCellWithIdentifier:SwitchCellID];
if( aCell == nil ) {
aCell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SwitchCellID] autorelease];
aCell.textLabel.text = [NSString stringWithFormat:@"Option %d", [indexPath row] + 1];
aCell.selectionStyle = UITableViewCellSelectionStyleNone;
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
aCell.accessoryView = switchView;
[switchView setOn:YES animated:NO];
[switchView addTarget:self action:@selector(soundSwitched:) forControlEvents:UIControlEventValueChanged];
[switchView release];
}

return aCell;
}

There's no magic here: it's what I do in the PuzzleTiles options screen, and it's what Apple does in the Settings app.  No big whoop.

Alright, now let's jam this bad boy into an alert view.

- (void) doAlertWithTableView {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Preferences"
message:@"\n\n\n\n\n\n\n"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK", nil];

UITableView *myView = [[[UITableView alloc] initWithFrame:CGRectMake(10, 40, 264, 150)
style:UITableViewStyleGrouped] autorelease];
myView.delegate = self;
myView.dataSource = self;
myView.backgroundColor = [UIColor clearColor];
[alert addSubview:myView];

[alert show];
[alert release];
}

That's it!  The only real trick (just like with doing with with a UITextField or a UIWebView, is to put some linefeeds in your message to make the alert taller to fit your view.

Here's how she looks:

UIAlertView with UITableView screenshot

Next time I'll try writing a post that *doesn't* feature a UIAlertView! Yay!

3 comments: