Shrinking Tables! (As seen in Spotlight)
Want to create tables as seen in Spotlight or Weather? It’s easier done than said : )
Note, this uses the Spotlight “cheater” method of simply drawing some pseudo corners over the table, as opposed to the Weather.app approach of masking off the table to remove corners. That said, as long as you’re using solid colors, the result will be identical.
First off, we want to open a new view controller based application. and slap in a simple UITableView with the grouped style. Go ahead and add the UITableView as a subview of your viewController.view.
Next, we’ll place a call our getCornersforRect:withColor: message. This will construct a UIImage of the corners that we want to apply. That image will be added to a new UIImageView that will be added on top of our UITableView.
And you’re done. Literally. See, this wasn’t so bad, was it? : )
CondensingTableViewController.h
#import <UIKit/UIKit.h> @interface CondensingTableViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>{ UISearchBar *searchBar; } @property (nonatomic, retain) IBOutlet UISearchBar *searchBar; - (UIImage *)getCornersforRect:(CGRect)rect withColor:(UIColor *)color; @end
Note, we only add in the UISearchBar property so we can have a reference for color matching the bar to the table.
CondensingTableViewController.m
// // CondensingTableViewController.m // CondensingTable // // Created by Skylar Cantu on 7/22/09. // Copyright Skylar Cantu 2009. All rights reserved. // #import "CondensingTableViewController.h" #define BG_COLOR [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0] //Set this to any color @interface CondensingTableViewController (PrivateMethods) - (UIColor *)convertColorFromGrayScaleToRGBIfNecessary:(UIColor *)color; @end @implementation CondensingTableViewController @synthesize searchBar; - (void)loadView { [super loadView]; self.view.backgroundColor = BG_COLOR; self.searchBar.tintColor = BG_COLOR; UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 50, 320, 320) style:UITableViewStyleGrouped]; tableView.backgroundColor = BG_COLOR; tableView.dataSource = self; tableView.delegate = self; tableView.indicatorStyle = UIScrollViewIndicatorStyleWhite; [self.view addSubview:tableView]; [tableView release]; UIImageView *cornersView = [[UIImageView alloc] initWithImage:[self getCornersforRect:tableView.bounds withColor:tableView.backgroundColor]]; [self.view addSubview:cornersView]; cornersView.center = tableView.center; [cornersView release]; } - (UIImage *)getCornersforRect:(CGRect)rect withColor:(UIColor *)color { color = [self convertColorFromGrayScaleToRGBIfNecessary:color]; //Method uses a RGB color. If color is monochrome (black, gray, white), then we must convert the color UIGraphicsBeginImageContext(rect.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextClearRect(context, rect); CGContextSetLineWidth(context, 0.0f); const CGFloat *clr = CGColorGetComponents(color.CGColor); CGContextSetRGBFillColor(context, clr[0], clr[1], clr[2], clr[3]); CGContextMoveToPoint(context, 0, 0); CGContextAddLineToPoint(context, rect.size.width, 0); CGContextAddLineToPoint(context, rect.size.width, rect.size.height); CGContextAddLineToPoint(context, 0, rect.size.height); CGContextClosePath(context); CGContextSetLineWidth(context, 3.0f); CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); CGFloat radius = 10.0; CGFloat minx = 10, midx = 155, maxx = 310; CGFloat miny = 10, midy = 155, maxy = 310; CGContextMoveToPoint(context, minx, midy); CGContextAddArcToPoint(context, minx, miny, midx, miny, radius); CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius); CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius); CGContextClosePath(context); CGContextDrawPath(context, kCGPathEOFill); CGContextEOClip(context); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (void)viewDidUnload { } - (void)dealloc { [searchBar release]; [super dealloc]; } #pragma mark #pragma mark TableViewDataSource Methods - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section { switch (section) { case 0: return 10; break; default: return 0; break; } return 0; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; cell.selectionStyle = (CGColorSpaceGetModel(CGColorGetColorSpace(tableView.backgroundColor.CGColor)) == kCGColorSpaceModelMonochrome) ? UITableViewCellSelectionStyleGray : UITableViewCellSelectionStyleBlue; } cell.textLabel.text = [NSString stringWithFormat:@"%d", indexPath.row + 1]; return cell; } #pragma mark #pragma mark TableViewDelegate Methods - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES]; } #pragma mark #pragma mark PrivateMethods - (UIColor *)convertColorFromGrayScaleToRGBIfNecessary:(UIColor *)color { if (CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) == kCGColorSpaceModelMonochrome) { const CGFloat *clr = CGColorGetComponents(color.CGColor); color = [UIColor colorWithRed:clr[0] green:clr[0] blue:clr[0] alpha:clr[1]]; } return color; } @end
First off, we define the color that we want everything to be. This is solely for convenience. Immediately, we interface and prototype a private method that converts the color from monochrome to RGB if necessary. We make this private because we don’t want other classes using out class’ method to do its dirty work. In an actual app environment, I would have this method yanked out of this object and placed in a centralized header that all the objects import. That way we only need one copy of the method.
Creating what we see is very simply, set the background color, set the UISearchBar tintColor, and create our table as we would any other UITableView.
When we create the corners, we use a pointer to the table’s backgroundColor as opposed to what we defined. This is in case something changes, we want to make absolutely sure that we are coloring the corners to match the table. To see why this is important, feel free to change that color to another color that doesn’t match the table.
To draw the corners, simply use standard CoreGraphics and UIKit functions to create a new UIImage of our corners. Really, it’s a table frame. Return that, add it to our table as a subview (in a UIImageView, of course), and compile away!
Side note, when the cell is first created in our table’s cellForRow method, we check the colorSpace of the tableView’s background color. If it is monochrome, we change the selection style to match.
Download link: http://www.touchrepo.com/SampleCode/CondensingTable.zip
More comments:ipodtouchfans.com
Comments
Tell me what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!
