[Sample Code] Condensing Tables (ie, Spotlight, Weather)

Discussion in 'iOS Development' started by SkylarEC, Jul 28, 2009.

  1. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,642
    Likes Received:
    129
    Want to create tables as seen in Spotlight or Weather? It's easier done than said : )

    Please Register or Log in to view images


    Please Register or Log in to view images

    Please Register or Log in to view images



    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
    [OBJC]#import <UIKit/UIKit.h>

    @interface CondensingTableViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
    UISearchBar *searchBar;
    }

    @property (nonatomic, retain) IBOutlet UISearchBar *searchBar;

    - (UIImage *)getCornersforRect

    Please Register or Log in to view images

    CGRect)rect withColor

    Please Register or Log in to view images

    UIColor *)color;

    @end[/OBJC]

    Note, we only add in the UISearchBar property so we can have a reference for color matching the bar to the table.


    CondensingTableViewController.m
    [OBJC]//
    // 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

    Please Register or Log in to view images

    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

    Please Register or Log in to view images

    CGRect)rect withColor

    Please Register or Log in to view images

    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

    Please Register or Log in to view images

    UITableView *)tableView {
    return 1;
    }

    - (NSInteger)tableView

    Please Register or Log in to view images

    UITableView *)table numberOfRowsInSection

    Please Register or Log in to view images

    NSInteger)section {
    switch (section) {
    case 0: return 10; break;
    default: return 0; break;
    }

    return 0;
    }

    - (UITableViewCell *)tableView

    Please Register or Log in to view images

    UITableView *)tableView cellForRowAtIndexPath

    Please Register or Log in to view images

    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

    Please Register or Log in to view images

    "%d", indexPath.row + 1];

    return cell;
    }


    #pragma mark
    #pragma mark TableViewDelegate Methods

    - (void)tableView

    Please Register or Log in to view images

    UITableView *)tableView didSelectRowAtIndexPath

    Please Register or Log in to view images

    NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];
    }


    #pragma mark
    #pragma mark PrivateMethods

    - (UIColor *)convertColorFromGrayScaleToRGBIfNecessary

    Please Register or Log in to view images

    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[/OBJC]


    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

Share This Page