Swift Regex Deep Dive
iOS MacOur introductory guide to Swift Regex. Learn regular expressions in Swift including RegexBuilder examples and strongly-typed captures.
The iPhone SDK has now been around long enough where we can start to pick out good practices in using some of the more “fuzzy” areas. There are two small, but important, practices that can make your life much easier.
###
Buttons in UITableViewCells
Sometimes, you will want to have a button or some sort of control in a UITableViewCell subclass. You could have many rows, and each one has a button, and that button should have a different result depending on what row it is in.
In sticking with the MVC paradigm, how do you accomplish this? You have to be able to set the target-action pair for these buttons and you also have to decide which row’s button was pressed.
Well, you don’t even have to look at the UITableViewCell, you are really only concerned with the button. A UIButton (or any UIControl) is a subclass of UIView. Every UIView has an integer instance variable called tag. You can use this tag to specify the row the button is currently in.
Your UITableViewCell subclass interface should look like this:
`
@interface ButtonCell : UITableViewCell
{
UIButton *button;
}
@property (readonly) UIButton *button;
@end
`
And your cell retrieval method should look like this:
`
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ButtonCell *aCell = (ButtonCell *)[tableView
dequeueReusableCellWithIdentifier:@"ButtonCell"];
if(!aCell)
{
aCell = [[[ButtonCell alloc] initWithFrame:CGRectZero
reuseIdentifier:@"ButtonCell"]
autorelease];
[[aCell button] addTarget:self
action:@selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
}
[[aCell button] setTag:[indexPath row]];
return aCell;
}
And finally, your action message should do this:
- (void)buttonPressed:(id)sender
{
int rowOfButton = [sender tag];
[[internalData objectAtIndex:rowOfButton] performFunStuff];
}
`
All there is to it.
###
Instantiating UIViewController subclasses
XIB files are confusing. Chaining UIViewController XIB files and creating instances of them in another XIB file is even more confusing. And quite pointless. There is a much better way to do it.
First, you have to decide if you want to use a XIB file or not. The only reason to use a XIB file is if you have a complicated user interface that needs to be set up via Interface Builder. Otherwise, if you have a single view like a UITableView, UIImageView or UIView, simply implement loadView.
Now, regardless of how you are creating the interface, all UIViewController subclasses (save the standard ones, like UITableViewController, UINavigationController and UITabBarController) should be instantiated in code and sent an init message.
`
ViewControllerSubclass *vcs = [[ViewControllerSubclass alloc] init];
`
You are probably wondering, “Uhh… if I just send it init, how do I load its view from a XIB?” Good question. You will be overriding the init method of your UIViewController subclass (and overriding the superclasses designated initializer).
`
- (id)init
{
return [super initWithNibName:@"ViewControllerSubclass" bundle:nil];
}
- (id)initWithNibName:(NSString *)name bundle:(NSBundle *)bundle
{
return [self init];
}
`
How does this work out in code? Let’s pretend you have two UIViewController subclasses, RootViewController and DetailViewController. They are both intended to be part of a UINavigationController.
In your application delegate, you should be doing this:
`
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
RootViewController *rootViewController =
[[RootViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:rootViewController];
[window addSubview:[navController view]];
[window makeKeyAndVisible];
}
`
In RootViewController’s implementation, you can do a little something like this:
`
- (void)viewDidLoad
{
if(!detailViewController)
detailViewController = [[DetailViewController alloc] init];
}
`
Therefore, none of your other classes need to know anything about any other UIViewController subclass. They just know if they want an instance of it – with a fully configured user interface – they can just send it init.
Easy enough.
Our introductory guide to Swift Regex. Learn regular expressions in Swift including RegexBuilder examples and strongly-typed captures.
The Combine framework in Swift is a powerful declarative API for the asynchronous processing of values over time. It takes full advantage of Swift...
SwiftUI has changed a great many things about how developers create applications for iOS, and not just in the way we lay out our...