扩展UIView行为,自动转换viewWithtag。
UIView-TagExtensions.h
/* Erica Sadun, http://ericasadun.com iPhone Developer's Cookbook, 3.0 Edition BSD License, Use at your own risk */ #import <UIKit/UIKit.h> #ifdef _USE_OS_3_OR_LATER #import <MapKit/MapKit.h> #endif @interface UIView (TagExtensions) - (UIAlertView *) alertViewWithTag: (NSInteger) aTag; - (UIActionSheet *) actionSheetWithTag: (NSInteger) aTag; - (UITableView *) tableViewWithTag: (NSInteger) aTag; - (UITableViewCell *) tableViewCellWithTag: (NSInteger) aTag; - (UIImageView *) imageViewWithTag: (NSInteger) aTag; - (UIWebView *) webViewWithTag: (NSInteger) aTag; - (UITextView *) textViewWithTag: (NSInteger) aTag; - (UIScrollView *) scrollViewWithTag: (NSInteger) aTag; - (UIPickerView *) pickerViewWithTag: (NSInteger) aTag; - (UIDatePicker *) datePickerWithTag: (NSInteger) aTag; - (UISegmentedControl *) segmentedControlWithTag: (NSInteger) aTag; - (UILabel *) labelWithTag: (NSInteger) aTag; - (UIButton *) buttonWithTag: (NSInteger) aTag; - (UITextField *) textFieldWithTag: (NSInteger) aTag; - (UISwitch *) switchWithTag: (NSInteger) aTag; - (UISlider *) sliderWithTag: (NSInteger) aTag; - (UIProgressView *) progressViewWithTag: (NSInteger) aTag; - (UIActivityIndicatorView *) activityIndicatorViewWithTag: (NSInteger) aTag; - (UIPageControl *) pageControlWithTag: (NSInteger) aTag; - (UIWindow *) windowWithTag: (NSInteger) aTag; - (UISearchBar *) searchBarWithTag: (NSInteger) aTag; - (UINavigationBar *) navigationBarWithTag: (NSInteger) aTag; - (UIToolbar *) toolbarWithTag: (NSInteger) aTag; - (UITabBar *) tabBarWithTag: (NSInteger) aTag; #ifdef _USE_OS_3_OR_LATER - (MKMapView *) mapViewWithTag: (NSInteger) aTag; #endif @endUIView-TagExtensions.m
/* Erica Sadun, http://ericasadun.com iPhone Developer's Cookbook, 3.0 Edition BSD License, Use at your own risk */ #import "UIView-TagExtensions.h" @implementation UIView (TagExtensions) - (UIAlertView *) alertViewWithTag: (NSInteger) aTag { return (UIAlertView *)[self viewWithTag:aTag]; } - (UIActionSheet *) actionSheetWithTag: (NSInteger) aTag { return (UIActionSheet *)[self viewWithTag:aTag]; } - (UITableView *) tableViewWithTag: (NSInteger) aTag { return (UITableView *)[self viewWithTag:aTag]; } - (UITableViewCell *) tableViewCellWithTag: (NSInteger) aTag { return (UITableViewCell *)[self viewWithTag:aTag]; } - (UIImageView *) imageViewWithTag: (NSInteger) aTag { return (UIImageView *)[self viewWithTag:aTag]; } - (UIWebView *) webViewWithTag: (NSInteger) aTag { return (UIWebView *)[self viewWithTag:aTag]; } - (UITextView *) textViewWithTag: (NSInteger) aTag { return (UITextView *)[self viewWithTag:aTag]; } - (UIScrollView *) scrollViewWithTag: (NSInteger) aTag { return (UIScrollView *)[self viewWithTag:aTag]; } - (UIPickerView *) pickerViewWithTag: (NSInteger) aTag { return (UIPickerView *)[self viewWithTag:aTag]; } - (UIDatePicker *) datePickerWithTag: (NSInteger) aTag { return (UIDatePicker *)[self viewWithTag:aTag]; } - (UISegmentedControl *) segmentedControlWithTag: (NSInteger) aTag { return (UISegmentedControl *)[self viewWithTag:aTag]; } - (UILabel *) labelWithTag: (NSInteger) aTag { return (UILabel *)[self viewWithTag:aTag]; } - (UIButton *) buttonWithTag: (NSInteger) aTag { return (UIButton *)[self viewWithTag:aTag]; } - (UITextField *) textFieldWithTag: (NSInteger) aTag { return (UITextField *)[self viewWithTag:aTag]; } - (UISwitch *) switchWithTag: (NSInteger) aTag { return (UISwitch *)[self viewWithTag:aTag]; } - (UISlider *) sliderWithTag: (NSInteger) aTag { return (UISlider *)[self viewWithTag:aTag]; } - (UIProgressView *) progressViewWithTag: (NSInteger) aTag { return (UIProgressView *)[self viewWithTag:aTag]; } - (UIActivityIndicatorView *) activityIndicatorViewWithTag: (NSInteger) aTag { return (UIActivityIndicatorView *)[self viewWithTag:aTag]; } - (UIPageControl *) pageControlWithTag: (NSInteger) aTag { return (UIPageControl *)[self viewWithTag:aTag]; } - (UIWindow *) windowWithTag: (NSInteger) aTag { return (UIWindow *)[self viewWithTag:aTag]; } - (UISearchBar *) searchBarWithTag: (NSInteger) aTag { return (UISearchBar *)[self viewWithTag:aTag]; } - (UINavigationBar *) navigationBarWithTag: (NSInteger) aTag { return (UINavigationBar *)[self viewWithTag:aTag]; } - (UIToolbar *) toolbarWithTag: (NSInteger) aTag { return (UIToolbar *)[self viewWithTag:aTag]; } - (UITabBar *) tabBarWithTag: (NSInteger) aTag { return (UITabBar *)[self viewWithTag:aTag]; } #ifdef _USE_OS_3_OR_LATER - (MKMapView *) mapViewWithTag: (NSInteger) aTag { return (MKMapView *)[self viewWithTag:aTag]; } #endif @end
6.6 命名视图
扩展UIView行为,自动转换viewWithtag根据名字。
UIView-NameExtensions.h
/* Erica Sadun, http://ericasadun.com iPhone Developer's Cookbook, 3.0 Edition BSD License, Use at your own risk */ #import <UIKit/UIKit.h> #ifdef _USE_OS_3_OR_LATER #import <MapKit/MapKit.h> #endif @interface UIView (NameExtensions) - (NSInteger) registerName: (NSString *) aName; - (BOOL) unregisterName: (NSString *) aName; - (UIView *) viewNamed: (NSString *) aName; - (UIAlertView *) alertViewNamed: (NSString *) aName; - (UIActionSheet *) actionSheetNamed: (NSString *) aName; - (UITableView *) tableViewNamed: (NSString *) aName; - (UITableViewCell *) tableViewCellNamed: (NSString *) aName; - (UIImageView *) imageViewNamed: (NSString *) aName; - (UIWebView *) webViewNamed: (NSString *) aName; - (UITextView *) textViewNamed: (NSString *) aName; - (UIScrollView *) scrollViewNamed: (NSString *) aName; - (UIPickerView *) pickerViewNamed: (NSString *) aName; - (UIDatePicker *) datePickerNamed: (NSString *) aName; - (UISegmentedControl *) segmentedControlNamed: (NSString *) aName; - (UILabel *) labelNamed: (NSString *) aName; - (UIButton *) buttonNamed: (NSString *) aName; - (UITextField *) textFieldNamed: (NSString *) aName; - (UISwitch *) switchNamed: (NSString *) aName; - (UISlider *) sliderNamed: (NSString *) aName; - (UIProgressView *) progressViewNamed: (NSString *) aName; - (UIActivityIndicatorView *) activityIndicatorViewNamed: (NSString *) aName; - (UIPageControl *) pageControlNamed: (NSString *) aName; - (UIWindow *) windowNamed: (NSString *) aName; - (UISearchBar *) searchBarNamed: (NSString *) aName; - (UINavigationBar *) navigationBarNamed: (NSString *) aName; - (UIToolbar *) toolbarNamed: (NSString *) aName; - (UITabBar *) tabBarNamed: (NSString *) aName; #ifdef _USE_OS_3_OR_LATER - (MKMapView *) mapViewNamed: (NSString *) aName; #endif @end
UIView-NameExtensions.m
/* Erica Sadun, http://ericasadun.com iPhone Developer's Cookbook, 3.0 Edition BSD License, Use at your own risk */ #import "UIView-NameExtensions.h" @interface ViewIndexer : NSObject { NSMutableDictionary *tagdict; NSInteger count; } @property (nonatomic, retain) NSMutableDictionary *tagdict; @end @implementation ViewIndexer @synthesize tagdict; #pragma mark sharedInstance static ViewIndexer *sharedInstance = nil; +(ViewIndexer *) sharedInstance { if(!sharedInstance) sharedInstance = [[self alloc] init]; return sharedInstance; } - (id) init { if (!(self = [super init])) return self; self.tagdict = [NSMutableDictionary dictionary]; count = 10000; return self; } - (void) dealloc { self.tagdict = nil; [super dealloc]; } #pragma mark registration // Pull a new number and increase the count - (NSInteger) pullNumber { return count++; } // Check to see if name exists in dictionary - (BOOL) nameExists: (NSString *) aName { return [self.tagdict objectForKey:aName] != nil; } // Pull out first matching name for tag - (NSString *) nameForTag: (NSInteger) aTag { NSNumber *tag = [NSNumber numberWithInt:aTag]; NSArray *names = [self.tagdict allKeysForObject:tag]; if (!names) return nil; if ([names count] == 0) return nil; return [names objectAtIndex:0]; } // Return the tag for a registered name. 0 if not found - (NSInteger) tagForName: (NSString *)aName { NSNumber *tag = [self.tagdict objectForKey:aName]; if (!tag) return 0; return [tag intValue]; } // Unregistering reverts tag to 0 - (BOOL) unregisterName: (NSString *) aName forView: (UIView *) aView { NSNumber *tag = [self.tagdict objectForKey:aName]; // tag not found if (!tag) return NO; // tag does not match registered name if (aView.tag != [tag intValue]) return NO; aView.tag = 0; [self.tagdict removeObjectForKey:aName]; return YES; } // Register a new name. Names will not re-register (unregister first, please). // If a view is already registered, it is unregistered and re-registered - (NSInteger) registerName:(NSString *)aName forView: (UIView *) aView { // You cannot re-register an existing name if ([[ViewIndexer sharedInstance] nameExists:aName]) return 0; // Check to see if the view is named already. If so, unregister. NSString *currentName = [self nameForTag:aView.tag]; if (currentName) [self unregisterName:currentName forView:aView]; // Register the existing tag or pull a new tag if aView.tag is 0 if (!aView.tag) aView.tag = [[ViewIndexer sharedInstance] pullNumber]; [self.tagdict setObject:[NSNumber numberWithInt:aView.tag] forKey:aName]; return aView.tag; } @end @implementation UIView (NameExtensions) #pragma mark Registration - (NSInteger) registerName: (NSString *) aName { return [[ViewIndexer sharedInstance] registerName:aName forView:self]; } - (BOOL) unregisterName: (NSString *) aName { return [[ViewIndexer sharedInstance] unregisterName:aName forView:self]; } #pragma mark Typed Name Retrieval - (UIView *) viewNamed: (NSString *) aName { NSInteger tag = [[ViewIndexer sharedInstance] tagForName:aName]; return [self viewWithTag:tag]; } - (UIAlertView *) alertViewNamed: (NSString *) aName { return (UIAlertView *)[self viewNamed:aName]; } - (UIActionSheet *) actionSheetNamed: (NSString *) aName { return (UIActionSheet *)[self viewNamed:aName]; } - (UITableView *) tableViewNamed: (NSString *) aName { return (UITableView *)[self viewNamed:aName]; } - (UITableViewCell *) tableViewCellNamed: (NSString *) aName { return (UITableViewCell *)[self viewNamed:aName]; } - (UIImageView *) imageViewNamed: (NSString *) aName { return (UIImageView *)[self viewNamed:aName]; } - (UIWebView *) webViewNamed: (NSString *) aName { return (UIWebView *)[self viewNamed:aName]; } - (UITextView *) textViewNamed: (NSString *) aName { return (UITextView *)[self viewNamed:aName]; } - (UIScrollView *) scrollViewNamed: (NSString *) aName { return (UIScrollView *)[self viewNamed:aName]; } - (UIPickerView *) pickerViewNamed: (NSString *) aName { return (UIPickerView *)[self viewNamed:aName]; } - (UIDatePicker *) datePickerNamed: (NSString *) aName { return (UIDatePicker *)[self viewNamed:aName]; } - (UISegmentedControl *) segmentedControlNamed: (NSString *) aName { return (UISegmentedControl *)[self viewNamed:aName]; } - (UILabel *) labelNamed: (NSString *) aName { return (UILabel *)[self viewNamed:aName]; } - (UIButton *) buttonNamed: (NSString *) aName { return (UIButton *)[self viewNamed:aName]; } - (UITextField *) textFieldNamed: (NSString *) aName { return (UITextField *)[self viewNamed:aName]; } - (UISwitch *) switchNamed: (NSString *) aName { return (UISwitch *)[self viewNamed:aName]; } - (UISlider *) sliderNamed: (NSString *) aName { return (UISlider *)[self viewNamed:aName]; } - (UIProgressView *) progressViewNamed: (NSString *) aName { return (UIProgressView *)[self viewNamed:aName]; } - (UIActivityIndicatorView *) activityIndicatorViewNamed: (NSString *) aName { return (UIActivityIndicatorView *)[self viewNamed:aName]; } - (UIPageControl *) pageControlNamed: (NSString *) aName { return (UIPageControl *)[self viewNamed:aName]; } - (UIWindow *) windowNamed: (NSString *) aName { return (UIWindow *)[self viewNamed:aName]; } - (UISearchBar *) searchBarNamed: (NSString *) aName { return (UISearchBar *)[self viewNamed:aName]; } - (UINavigationBar *) navigationBarNamed: (NSString *) aName { return (UINavigationBar *)[self viewNamed:aName]; } - (UIToolbar *) toolbarNamed: (NSString *) aName { return (UIToolbar *)[self viewNamed:aName]; } - (UITabBar *) tabBarNamed: (NSString *) aName { return (UITabBar *)[self viewNamed:aName]; } #ifdef _USE_OS_3_OR_LATER - (MKMapView *) mapViewNamed: (NSString *) aName { return (MKMapView *)[self viewNamed:aName]; } #endif @end
6.19 当视图显示时反弹视图
扩展UIView行为,使得动画可以连续播放。
UIView-ModalAnimationHelper.h /* Erica Sadun, http://ericasadun.com iPhone Developer's Cookbook, 3.0 Edition BSD License, Use at your own risk */ #import <UIKit/UIKit.h> @interface UIView (ModalAnimationHelper) + (void) commitModalAnimations; @end
UIView-ModalAnimationHelper.m /* Erica Sadun, http://ericasadun.com iPhone Developer's Cookbook, 3.0 Edition BSD License, Use at your own risk Runloop credit to Kenny TM. Mistakes are mine. */ #import "UIView-ModalAnimationHelper.h" @interface UIViewDelegate : NSObject { CFRunLoopRef currentLoop; } @end @implementation UIViewDelegate -(id) initWithRunLoop: (CFRunLoopRef)runLoop { if (self = [super init]) currentLoop = runLoop; return self; } -(void) animationFinished: (id) sender { CFRunLoopStop(currentLoop); } @end @implementation UIView (ModalAnimationHelper) + (void) commitModalAnimations { CFRunLoopRef currentLoop = CFRunLoopGetCurrent(); UIViewDelegate *uivdelegate = [[UIViewDelegate alloc] initWithRunLoop:currentLoop]; [UIView setAnimationDelegate:uivdelegate]; [UIView setAnimationDidStopSelector:@selector(animationFinished:)]; [UIView commitAnimations]; CFRunLoopRun(); [uivdelegate release]; } @end
main.m /* Erica Sadun, http://ericasadun.com iPhone Developer's Cookbook, 3.0 Edition BSD License, Use at your own risk */ #import <UIKit/UIKit.h> #import "UIView-ModalAnimationHelper.h" #define COOKBOOK_PURPLE_COLOR [UIColor colorWithRed:0.20392f green:0.19607f blue:0.61176f alpha:1.0f] #define BARBUTTON(TITLE, SELECTOR) [[[UIBarButtonItem alloc] initWithTitle:TITLE style:UIBarButtonItemStylePlain target:self action:SELECTOR] autorelease] @interface TestBedViewController : UIViewController { int direction; } @end @implementation TestBedViewController - (void) animate: (id) sender { // Hide the bar button and show the view self.navigationItem.rightBarButtonItem = nil; [self.view viewWithTag:101].alpha = 1.0f; // Bounce to 115% of the normal size [UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationDuration:0.4f]; [self.view viewWithTag:101].transform = CGAffineTransformMakeScale(1.15f, 1.15f); [UIView commitModalAnimations]; // Return back to 100% [UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationDuration:0.3f]; [self.view viewWithTag:101].transform = CGAffineTransformMakeScale(1.0f, 1.0f); [UIView commitModalAnimations]; // Pause for a second and appreciate the presentation [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0f]]; // Slowly zoom back down and hide the view [UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationDuration:1.0f]; [self.view viewWithTag:101].transform = CGAffineTransformMakeScale(0.01f, 0.01f); [UIView commitModalAnimations]; // Restore the bar button [self.view viewWithTag:101].alpha = 0.0f; self.navigationItem.rightBarButtonItem = BARBUTTON(@"Bounce", @selector(animate:)); } - (void) viewDidLoad { direction = 0; self.navigationController.navigationBar.tintColor = COOKBOOK_PURPLE_COLOR; self.navigationItem.rightBarButtonItem = BARBUTTON(@"Bounce", @selector(animate:)); [self.view viewWithTag:101].transform = CGAffineTransformMakeScale(0.01f, 0.01f); [self.view viewWithTag:101].alpha = 0.0f; } @end @interface TestBedAppDelegate : NSObject <UIApplicationDelegate> @end @implementation TestBedAppDelegate - (void)applicationDidFinishLaunching:(UIApplication *)application { UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[TestBedViewController alloc] init]]; [window addSubview:nav.view]; [window makeKeyAndVisible]; } @end int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, @"TestBedAppDelegate"); [pool release]; return retVal; }