Tuesday 31 January 2012

Convert_stringToDate,DateToString...


-(NSDate *)convertStringToDate:(NSString *) date {
        NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];

//This bellow 3 lines for system date issue
    NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
    assert(enUSPOSIXLocale != nil);
    
    [formatter setLocale:enUSPOSIXLocale];

    [formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

        NSDate *nowDate = [[[NSDate alloc] init] autorelease];
        [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];// set format here which format in string date
        date = [date stringByReplacingOccurrencesOfString:@"+0000" withString:@""];
        nowDate = [formatter dateFromString:date];
        // NSLog(@"date============================>>>>>>>>>>>>>>> : %@", nowDate);
        return nowDate;
}

    NSString *str = @"Tue, 24 May 2011 15:42:01 +0000";
    
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];

//This bellow 3 lines for system date issue
    NSLocale *enUSPOSIXLocale = [[NSLocale allocinitWithLocaleIdentifier:@"en_US_POSIX"];
    assert(enUSPOSIXLocale != nil);
    
    [formatter setLocale:enUSPOSIXLocale];

    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

    [dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss z"];

    NSDate *date = [dateFormatter dateFromString: str];
    
    dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [dateFormatter setDateFormat:@"dd/MM/yyyy hh:mm:ss a"];
    
    NSString *convertedString = [dateFormatter stringFromDate:date];
    NSLog(@"Converted String : %@",convertedString);




    NSLog(@"Date String Arrived =====>>>%@",strDate);
    NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];

//This bellow 3 lines for system date issue
    NSLocale *enUSPOSIXLocale = [[NSLocale allocinitWithLocaleIdentifier:@"en_US_POSIX"];
    assert(enUSPOSIXLocale != nil);
    
    [dateFormatter setLocale:enUSPOSIXLocale];


    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

    [dateFormatter setDateFormat:@"dd-MM-yyyy hh:mm:ss a"];
    NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
    NSLog(dateString); 


Date Formate Info For iPhone sdk...


Update : If you have this type of String "2013-01-22T18:24:52.963" then you can convert it like bellow...

First use this my custom method for convert any Date string in another date string with different format


-(NSString *)changeDateFormat:(NSString*)stringDate dateFormat:(NSString*)dateFormat getwithFormat:(NSString *)getwithFormat{
    
    
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];

//this bellow 3 lines used for set system related date format issue
        NSLocale *enUSPOSIXLocale = [[NSLocale allocinitWithLocaleIdentifier:@"en_US_POSIX"];
    assert(enUSPOSIXLocale != nil);
    
       [dateFormatter setLocale:enUSPOSIXLocale];

       [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

    [dateFormatter setDateFormat:dateFormat];
    
    NSDate *date = [dateFormatter dateFromString:stringDate];
    date = [dateFormatter dateFromString:stringDate];
    dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [dateFormatter setDateFormat:getwithFormat];
    
    NSString *convertedString = [dateFormatter stringFromDate:date];
    NSLog(@"Converted String : %@",convertedString);
    return convertedString;
}

just call this method like bellow...

NSString *strDateNewFormat  = [self changeDateFormat:[[arrDieryDetail valueForKey:@"CreateDate"] objectAtIndex:0] dateFormat:@"
yyyy-MM-dd'T'HH:mm:ss.SSS" getwithFormat:@"dd/MM/yyyy"];
NSLog(@"New Date String : %@", strDateNewFormat);



Tutorial: 

It is quite common to have to display time information in your app, be it the current time, news feed’s creation date, scheduled meeting time or birthday reminders. However, not all of them are displayed the same way and may require different formatting. To do that with Objective-C for iPhone apps, NSDateFormatter is what we need.

In most cases, you’d just need to use the default styles defined in NSDateFormatterStyle.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSLog(@"%@", [dateFormatter stringFromDate:[NSDate date]]);

[dateFormatter release];

// Output: Dec 2, 2008 3:58 PM
But at times, you’d prefer to set your own time format, and that’s where it starts to get tricky.
It is actually quite simple, all you have to do is to create a format string to tell NSDateFormatter how to format your time string.
:
[dateFormatter setDateFormat:@"hh:mm:ss"]
:
// Output: 03:58:27
The problem is, the official documentation from apple doesn’t really tell you what specifiers are available to format your string. Even worse, it doesn’t conform to the ISO 8601 standard! What a bummer! And after a bit of searching on the net and still come up short, I have decided to just hack a little bit of code together to dump a list of specifiers and their results.
(EDIT: Apparently, there is now a link to the Unicode Date Field Symbol Table that Apple follows, even though my test shows that it still doesn’t conform 100% to the standard. Thanks Benjamin and Adam for finding it.)
a: AM/PM
A: 0~86399999 (Millisecond of Day)

c/cc: 1~7 (Day of Week)
ccc: Sun/Mon/Tue/Wed/Thu/Fri/Sat
cccc: Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday

d: 1~31 (0 padded Day of Month)
D: 1~366 (0 padded Day of Year)

e: 1~7 (0 padded Day of Week)
E~EEE: Sun/Mon/Tue/Wed/Thu/Fri/Sat
EEEE: Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday

F: 1~5 (0 padded Week of Month, first day of week = Monday)

g: Julian Day Number (number of days since 4713 BC January 1)
G~GGG: BC/AD (Era Designator Abbreviated)
GGGG: Before Christ/Anno Domini

h: 1~12 (0 padded Hour (12hr))
H: 0~23 (0 padded Hour (24hr))

k: 1~24 (0 padded Hour (24hr)
K: 0~11 (0 padded Hour (12hr))

L/LL: 1~12 (0 padded Month)
LLL: Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec
LLLL: January/February/March/April/May/June/July/August/September/October/November/December

m: 0~59 (0 padded Minute)
M/MM: 1~12 (0 padded Month)
MMM: Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec
MMMM: January/February/March/April/May/June/July/August/September/October/November/December

q/qq: 1~4 (0 padded Quarter)
qqq: Q1/Q2/Q3/Q4
qqqq: 1st quarter/2nd quarter/3rd quarter/4th quarter
Q/QQ: 1~4 (0 padded Quarter)
QQQ: Q1/Q2/Q3/Q4
QQQQ: 1st quarter/2nd quarter/3rd quarter/4th quarter

s: 0~59 (0 padded Second)
S: (rounded Sub-Second)

u: (0 padded Year)

v~vvv: (General GMT Timezone Abbreviation)
vvvv: (General GMT Timezone Name)

w: 1~53 (0 padded Week of Year, 1st day of week = Sunday, NB: 1st week of year starts from the last Sunday of last year)
W: 1~5 (0 padded Week of Month, 1st day of week = Sunday)

y/yyyy: (Full Year)
yy/yyy: (2 Digits Year)
Y/YYYY: (Full Year, starting from the Sunday of the 1st week of year)
YY/YYY: (2 Digits Year, starting from the Sunday of the 1st week of year)

z~zzz: (Specific GMT Timezone Abbreviation)
zzzz: (Specific GMT Timezone Name)
Z: +0000 (RFC 822 Timezone)
(Letters not listed here did not return any result.)
Basically, you put the above letters together in a NSString to tell NSDateFormatter what to display.
In most cases, you can concatenate a letter together a number of times, and you will get a 0 padded version of it up to the number of letters you have concatenated (eg: @”ssssss” => @”000059). In other cases, the longer concatenated version will give a different result (eg: @”M” => @”12, @”MMMM” => @”December”).
Also, some of the different letters seem to be giving out the same results (eg. the q’s & the Q’s), while others have subtle differences (eg. the v’s & the z’s). One of the silly one is the uppercase Y’s, where the year jumps ahead at the end of the year, so unless you really want that, it’s better to just stick with the lowercase y’s.
You can grab the sample code here: DateFormat
//******************************************
-(void)StringFromDate:(NSDate *)DateLocal{
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"EEE, d MMMM YYYY h:m:s a"];
    NSString *dateString = [dateFormat stringFromDate:DateLocal];  
    NSLog(@"Date is HERE  =====>> %@",dateString);
    [dateFormat release];
}





//***********************************************


-(NSString *)StringFromDate:(NSString *)DateLocal{
    DateLocal = [self trimString:DateLocal];
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];

//this bellow 3 lines used for set system related date format issue
        NSLocale *enUSPOSIXLocale = [[NSLocale allocinitWithLocaleIdentifier:@"en_US_POSIX"];
    assert(enUSPOSIXLocale != nil);
    
       [dateFormatter setLocale:enUSPOSIXLocale];

       [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];  
    [dateFormatter setDateFormat:@"EEEE, d MMMM YYYY H:m:s"];
    
    NSDate *date = [dateFormatter dateFromString: DateLocal];
    NSString *tt = [dateFormatter stringFromDate:date];
    NSDate *dateReturn = [dateFormatter dateFromString:tt];
    
    
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];

//this bellow 3 lines used for set system related date format issue
        NSLocale *enUSPOSIXLocale = [[NSLocale allocinitWithLocaleIdentifier:@"en_US_POSIX"];
    assert(enUSPOSIXLocale != nil);
    
       [dateFormat setLocale:enUSPOSIXLocale];


       [dateFormat setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

    [dateFormat setDateFormat:@"EEE, d MMMM YYYY h:m:s a"];
    NSString *dateString = [dateFormat stringFromDate:dateReturn];  
    NSLog(@"Date is HERE  =====>> %@",dateString);
    [dateFormat release];
    return dateString;
}
#pragma mark -
#pragma mark Extra Methods

-(NSString*)trimString:(NSString *)theString {
NSString *theStringTrimmed = [theString stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
return theStringTrimmed;
}


//*******************************************************

 NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
    components.month = 1;
    NSDate *oneMonthFromNow = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:[NSDate date] options:0];

//*******************************************************

-(NSString *)StringFromDate:(NSDate *)DateLocal{
    
    NSDateFormatter *prefixDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [prefixDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
    [prefixDateFormatter setDateFormat:@"MMMM d., y"];
    NSString * prefixDateString = [prefixDateFormatter stringFromDate:DateLocal];
    NSDateFormatter *monthDayFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [monthDayFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
    [monthDayFormatter setDateFormat:@"d"];         
    int date_day = [[monthDayFormatter stringFromDate:DateLocal] intValue];      
    NSString *suffix_string = @"|st|nd|rd|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|th|st|nd|rd|th|th|th|th|th|th|th|st";
    NSArray *suffixes = [suffix_string componentsSeparatedByString: @"|"];
    NSString *suffix = [suffixes objectAtIndex:date_day];   
    
    prefixDateString = [prefixDateString stringByReplacingOccurrencesOfString:@"." withString:suffix];
    NSString *dateString =prefixDateString;       
    //  NSLog(@"%@", dateString);
    return dateString;
}
//*******************************************************

Monday 30 January 2012

In Built Twitter use of ios5 in iphone sdk...



  1. - (IBAction)shareOnTwitter:(id)sender {
  2.    
  3.     TWTweetComposeViewController *twitter = [[TWTweetComposeViewController alloc] init];
  4.    
  5.     [twitter setInitialText:@"It's really that simple!"];
  6.     [twitter addImage:[UIImage imageNamed:@"twitter.png"]];
  7.  
  8.     [self presentViewController:twitter animated:YES completion:nil];
  9.        
  10.     twitter.completionHandler = ^(TWTweetComposeViewControllerResult res) {
  11.        
  12.         if(res == TWTweetComposeViewControllerResultDone)
  13.         {
  14.            
  15.             UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Succes!" message:@"Your Tweet was posted succesfully" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
  16.            
  17.             [alertView show];
  18.            
  19.            
  20.         }else if(res == TWTweetComposeViewControllerResultCancelled)
  21.         {
  22.            
  23.             UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your Tweet was not posted" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
  24.            
  25.             [alertView show];
  26.            
  27.         }
  28.        
  29.         [self dismissModalViewControllerAnimated:YES];
  30.        
  31.     };
  32.    
  33. }

Thursday 26 January 2012

DateFormater Function...


-(NSString *) dateInFormat:(NSString*) stringFormat {
        char buffer[80];
        const char *format = [stringFormat UTF8String];
        time_t rawtime;
        struct tm * timeinfo;
        time(&rawtime);
        timeinfo = localtime(&rawtime);
        strftime(buffer, 80, format, timeinfo);
        return [NSString  stringWithCString:buffer encoding:NSUTF8StringEncoding];
}

////////Like.......
 NSString *mydate =  [self dateInFormat:@"%Y%m%d-%H%M%S"];

Monday 23 January 2012

Search From TableView iPhone

////in .h file

:UITableviewController{

NSMutableArray *arrTableData;
    NSMutableArray *copyarrTableData;
    BOOL searching;
BOOL letUserSelectRow;
    
    IBOutlet UISearchBar *searchBar;

    OverlayViewController *ovController;
}
- (void) searchTableView;
- (void) doneSearching_Clicked:(id)sender;
@end

///in .m file
viewDidLoad{

//// JP - Searching....
    //Initialize the copy array.
copyarrTableData = [[NSMutableArray alloc] init];
    //Add the search bar
self.tableView.tableHeaderView = searchBar;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
searching = NO;
letUserSelectRow = YES;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    
if (searching)
return 1;
else
return 1;

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    //#warning Incomplete method implementation.
    // Return the number of rows in the section.
    if (searching)
return [copyarrTableData count];
    else{
        return [arrTableData count];
    }

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"MyCell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    // Configure the cell...
    if(searching) {
        
        objGetContInnerListData=[copyarrTableData objectAtIndex:indexPath.row];
        
        cell.textLabel.text=[NSString stringWithFormat:@"%@ %@",objGetContInnerListData.firstname,objGetContInnerListData.lastname];


    }
    else{
    objGetContInnerListData=[arrTableData objectAtIndex:indexPath.row];
    
    cell.textLabel.text=[NSString stringWithFormat:@"%@ %@",objGetContInnerListData.firstname,objGetContInnerListData.lastname];
//    cell.textLabel.text=objGetContInnerListData.firstname;
    }
    return cell;
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    
     ContactDetailView *detailViewController = [[ContactDetailView alloc] initWithNibName:@"ContactDetailView" bundle:nil];
    
    
    if(searching){
        
        objGetContInnerListData=[copyarrTableData objectAtIndex:indexPath.row];
        
        detailViewController.strautoid = objGetContInnerListData.autoid;
        detailViewController.objGetContInnerListData = objGetContInnerListData;
        [detailViewController.strautoid retain];
    }
    else{
        objGetContInnerListData=[arrTableData objectAtIndex:indexPath.row];
//        NSLog(@"\n\n DidSelect Obj Autoid : %@ %@ %@",objGetContactListData.autoid,objGetContactListData.clname,objGetContactListData.clid);
        detailViewController.objGetContInnerListData = objGetContInnerListData;
        detailViewController.strautoid = objGetContInnerListData.autoid;
        [detailViewController.strautoid retain]; 
    }
    [detailViewController.objGetContInnerListData retain];

    detailViewController.navigationItem.rightBarButtonItem = self.navigationItem.rightBarButtonItem;
    detailViewController.title = strtype;

     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     [detailViewController release];
     
}

#pragma mark -
#pragma mark Search Bar 

- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
//This method is called again when the user clicks back from the detail view.
//So the overlay is displayed on the results, which is something we do not want to happen.
if(searching)
return;
//Add the overlay view.
if(ovController == nil)
ovController = [[OverlayViewController alloc] initWithNibName:@"OverlayView" bundle:[NSBundle mainBundle]];
CGFloat yaxis = self.navigationController.navigationBar.frame.size.height;
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
//Parameters x = origion on x-axis, y = origon on y-axis.
CGRect frame = CGRectMake(0, yaxis, width, height);
ovController.view.frame = frame;
ovController.view.backgroundColor = [UIColor grayColor];
ovController.view.alpha = 0.5;
ovController.rvController = self;
[self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
searching = YES;
letUserSelectRow = NO;
self.tableView.scrollEnabled = NO;
//Add the done button.
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc
  initWithBarButtonSystemItem:UIBarButtonSystemItemDone 
  target:self action:@selector(doneSearching_Clicked:)] autorelease];
}

- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
    
//Remove all objects first.
[copyarrTableData removeAllObjects];
if([searchText length] > 0) {
[ovController.view removeFromSuperview];
searching = YES;
letUserSelectRow = YES;
self.tableView.scrollEnabled = YES;
[self searchTableView];
}
else {
[self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
searching = NO;
letUserSelectRow = NO;
self.tableView.scrollEnabled = NO;
}
[self.tableView reloadData];
}

- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar {
[self searchTableView];
}

- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (GetContInnerListData *obj in arrTableData)
{
// NSArray *array = obj.firstname;//[dictionary valueForKey:@"firstname"];
// [searchArray addObject:[NSString stringWithFormat:@"%@ %@",obj.firstname,obj.lastname]];
//        [searchArray addObject:obj.firstname];
        NSComparisonResult result = [obj.lastname compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
[copyarrTableData addObject:obj];
}

}
// for (NSString *sTemp in searchArray)
// {
// NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
//
// if (titleResultsRange.length > 0)
// [copyarrTableData addObject:sTemp];
// }
[searchArray release];
searchArray = nil;
}

- (void) doneSearching_Clicked:(id)sender {
searchBar.text = @"";
[searchBar resignFirstResponder];
letUserSelectRow = YES;
searching = NO;
self.navigationItem.rightBarButtonItem = nil;
self.tableView.scrollEnabled = YES;
[ovController.view removeFromSuperview];
[ovController release];
ovController = nil;
[self.tableView reloadData];
}

/////overlay class with xib
take view based new file only

/// overlay.h file

#import <UIKit/UIKit.h>

@class ContactInnerListView;

@interface OverlayViewController : UIViewController {

ContactInnerListView *rvController;
}

@property (nonatomic, retain) ContactInnerListView *rvController;

@end

/// overlay.m file
#import "OverlayViewController.h"
#import "ContactInnerListView.h"

@implementation OverlayViewController

@synthesize rvController;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[rvController doneSearching_Clicked:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}


- (void)dealloc {
[rvController release];
    [super dealloc];
}


@end





Friday 20 January 2012

PageOpenAnimation Like Book Page Open


////// .h file // -JP
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@interface PageOpenAnimationTutorialViewController : UIViewController {
    
    IBOutlet UIButton *openPageButton;
    IBOutlet UIImageView *pageImage;

}

- (IBAction) openPage:(id)sender;
- (void) pageOpenView:(UIView *)viewToOpen duration:(NSTimeInterval)duration;

@end



/////// .m file // -JP


- (IBAction) openPage:(id)sender {
    [self pageOpenView:pageImage duration:2.0f];
}

- (void) pageOpenView:(UIView *)viewToOpen duration:(NSTimeInterval)duration {
    // Remove existing animations before stating new animation
    [viewToOpen.layer removeAllAnimations];
    
    // Make sure view is visible
    viewToOpen.hidden = NO;
    
    // disable the view so it’s not doing anythign while animating
    viewToOpen.userInteractionEnabled = NO;
    // Set the CALayer anchorPoint to the left edge and
    // translate the button to account for the new
    // anchorPoint. In case you want to reuse the animation
    // for this button, we only do the translation and
    // anchor point setting once.
    if (viewToOpen.layer.anchorPoint.x != 0.0f) {
        viewToOpen.layer.anchorPoint = CGPointMake(0.0f, 0.5f);
        viewToOpen.center = CGPointMake(viewToOpen.center.x - viewToOpen.bounds.size.width/2.0f, viewToOpen.center.y);
    }
    // create an animation to hold the page turning
    CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
    transformAnimation.removedOnCompletion = NO;
    transformAnimation.duration = duration;
    transformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    // start the animation from the current state
    transformAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    // this is the basic rotation by 90 degree along the y-axis
    CATransform3D endTransform = CATransform3DMakeRotation(3.141f/2.0f,
                                                           0.0f,
                                                           -1.0f,
                                                           0.0f);
    // these values control the 3D projection outlook
    endTransform.m34 = 0.001f;
    endTransform.m14 = -0.0015f;
    transformAnimation.toValue = [NSValue valueWithCATransform3D:endTransform];
    // Create an animation group to hold the rotation
    CAAnimationGroup *theGroup = [CAAnimationGroup animation];
    
    // Set self as the delegate to receive notification when the animation finishes
    theGroup.delegate = self;
    theGroup.duration = duration;
    // CAAnimation-objects support arbitrary Key-Value pairs, we add the UIView tag
    // to identify the animation later when it finishes
    [theGroup setValue:[NSNumber numberWithInt:viewToOpen.tag] forKey:@"viewToOpenTag"];
    // Here you could add other animations to the array
    theGroup.animations = [NSArray arrayWithObjects:transformAnimation, nil];
    theGroup.removedOnCompletion = NO;
    // Add the animation group to the layer
    [viewToOpen.layer addAnimation:theGroup forKey:@"flipViewOpen"];
}

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
    // Get the tag from the animation, we use it to find the
    // animated UIView
    NSNumber *tag = [theAnimation valueForKey:@"viewToOpenTag"];
    // Find the UIView with the tag and do what you want
    // This only searches the first level subviews
    for (UIView *subview in self.view.subviews) {
        if (subview.tag == [tag intValue]) {
            // Code for what's needed to happen after
            // the animation finishes goes here.
            if (flag) {
                // Now we just hide the animated view since
                // animation.removedOnCompletion is not working
                // in animation groups. Hiding the view prevents it
                // from returning to the original state and showing.
                subview.hidden = YES;
            }
        }
    }
}