Archive

Archive for the ‘Mobile’ Category

iPhone – UITableViewCell Custom Selection Style Color

January 14th, 2010 derek Comments off

xcode-iconOddly, Apple has given you the ability to vastly customize the primary view of  a UITableViewCell. However, the selection style view is much more difficult to do such. Apple kindly gave us UITableViewSelectionStyleBlue/Gray/None. Well, that doesn’t always cut it does it?

There are already some very good tutorials on revamping the whole table view.  Google it! The best I came across was from Cocoa with Love – Custom UITableView.

However, this can be a bit overkill for some situations. It can also take a good bit of time to setup all the necessary images. What I needed was a quick and easy way to ‘theme’ the application and thus the selection style for a UITableViewCell. This needed to work with both plain and grouped table view styles and custom cells as well. You can see now why this may take  a while using the above methods.

Here is a quick and easy method to do just that.

SomeViewController.h

#import <UIKit/UIKit.h>

@interface SomeViewController : UITableViewController {
     UITableViewCell *currentSelectedCell;
}

@property (nonatomic, retain) UITableViewCell *currentSelectedCell;

- (void)setSelectedCell:(UITableViewCell *)selectedCell
     deselectedCell:(UITableViewCell *)deselectedCell;

@end

SomeViewController.m

#import "SomeViewController.h"

@implementation SomeViewController

@synthesize currentSelectedCell;

- (void)setSelectedCell:(UITableViewCell *)selectedCell deselectedCell:(UITableViewCell *)deselectedCell {
     //revert deselected cell
     if (deselectedCell != nil) {
          deselectedCell.backgroundColor = [UIColor whiteColor];
          for (UIView *subView in [deselectedCell.contentView subviews]) {
               if ([subView isKindOfClass:[UILabel class]]) {
                    UILabel *label = (UILabel *)subView;
                    label.textColor = [UIColor blackColor];
               }

               if ([subView isKindOfClass:[UITextField class]]) {
                    UITextField *textField = (UITextField *)subView;
                    textField.textColor = [UIColor blackColor];
               }
          }
     }

     //setup selected cell
     selectedCell.backgroundColor = [UIColor redColor]; //Some defined UIColor
     for (UIView *subView in [selectedCell.contentView subviews]) {
          if ([subView isKindOfClass:[UILabel class]]) {
               UILabel *label = (UILabel *)subView;
               label.textColor = [UIColor whiteColor];
          }

          if ([subView isKindOfClass:[UITextField class]]) {
               UITextField *textField = (UITextField *)subView;
               textField.textColor = [UIColor whiteColor];
          }
     }
}

#pragma mark -
#pragma mark Table View Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
     (NSIndexPath *)indexPath {

     setSelectedCell:[tableView cellForRowAtIndexPath:indexPath]
          deselectedCell:currentSelectedCell];

     currentSelectedCell = [tableView cellForRowAtIndexPath:indexPath];
}

#pragma mark -
#pragma mark Table View Data Source Methods

- (UITableViewCell *)tableView:(UITableView *)tableView
     cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     //........Setup UITableViewCell...........//

     cell.selectionStyle = UITableViewCellSelectionStyleNone;

     return cell;
}

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:
     (NSInteger)section {

     return count;
}

@end

Now, I’ve provided this in one class but what I’ve done is setup an ‘application’ singleton that has this function and is called from each UITableView’s didSelectRowAtIndexPath delegate. Works great on standard, custom, plain, and grouped views.

iPhone Development – Continuous Picker

December 31st, 2009 derek Comments off

Coming soon…been hard at work on some projects.

iPhone Development – Global Variables (Singleton)

November 6th, 2009 derek Comments off

xcode-iconIn iPhone development, if/when you need a single instance of a variable that can be shared and manipulated where and how should you implement this. Thus far I have found 2 ways of doing so. The first would be to add the global variables to your AppDelegate (which can be done and will be explained but isn’t the preferred method). The second and ‘correct’ way of going about globals is to create a Singleton.

For the following examples we will assume the global variable you are trying to implement is a User object.

User.h

#import <Foundation/Foundation.h>

@interface User : NSObject {

NSString *username;

NSString *password;

NSString *accountType;

}

@property (nonatomic, retain) NSString *username;

@property (nonatomic, retain) NSString *password;

@property (nonatomic, retain) NSString *accountType;

User.m

#import “User.h”

@implementation User

@synthesize username;

@synthesize password;

@synthesize accountType;


App Delegate Method

ApplicationAppDelegate.h

#import “User.h”


@interface ApplicationAppDelegate : NSObject <UIApplicationDelegate> {

NSManagedObjectModel *managedObjectModel;

NSManagedObjectContext *managedObjectContext;

NSPersistentStoreCoordinator *persistentStoreCoordinator;

UIWindow *window;

User *user;

}

@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;

@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;

@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain) User *user;


ApplicationAppDelegate.m

#import “ApplicationAppDelegate.h”

@implementation ApplicationAppDelegate

@synthesize window;

@synthesize user;

#pragma mark -

#pragma mark Application lifecycle

- (void)applicationDidFinishLaunching:(UIApplication *)application {

[window addSubview:tabBarController.view];

// Override point for customization after app launch

[window makeKeyAndVisible];

user = [[User alloc] init];

}

Then from any view controller you can access the Delegate variable as such.

SomeViewController.m

UIApplication *app = [UIApplication sharedApplication];

app.user.username = @”Username”;

While this can be done and will work. The overall use of the AppDelegate for this functionality is incorrect. The AppDelegate should be used for the following 2 reasons:

  • implemenations of the NSApplication delegate methods (includingapplicationDidFinishLaunching: to finalize application construction)
  • handling menu items for items that don’t exist in a window (for example, opening the application Preferences window)

So, on that note, lets implement a Singleton. The ‘correct’ way of creating a single global instance of an object that can be accessed and manipulated by the view controllers.


Singleton Method

First we need to make some changes to our User class as such:

User.h

#import <Foundation/Foundation.h>

@interface User : NSObject {

NSString *username;

NSString *password;

NSString *accountType;

}

@property (nonatomic, retain) NSString *username;

@property (nonatomic, retain) NSString *password;

@property (nonatomic, retain) NSString *accountType;

+ (User *)sharedUser;

@end

User.m

#import “User.h”

static User *sharedUser = nil;

@implementation User

@synthesize username;

@synthesize password;

@synthesize accountType;

#pragma mark -

#pragma mark Singleton Methods

+ (User *)sharedUser {

if(sharedUser == nil){

sharedUser = [[super allocWithZone:NULL] init];

}

return sharedUser;

}

+ (id)allocWithZone:(NSZone *)zone {

return [[self sharedManager] retain];

}

- (id)copyWithZone:(NSZone *)zone {

return self;

}

- (id)retain {

return self;

}

- (unsigned)retainCount {

return NSUIntegerMax;

}

- (void)release {

//do nothing

}

- (id)autorelease {

return self;

}

@end

Now, in any view controller we need to access/manipulate the ‘global’ user we can do:

SomeViewController.m

#import “SomeViewController.h”

#import “User.h”

@implementation SomeViewController

- (void)someFunction{

User *user = [User sharedUser];

user.username = @”Username”;

}

@end

References and resources that made this post and my learning possible.

- Updated: 11.17.09 – Reviewed Apple’s documentation on singletons and made the proper changes. Apple’s Singleton Documentation