How to programmatically transition between views in Tab Bar Controller

Leave a comment

Say you’ve got a uitabbarcontroller and you want to programatically switch from one to the other. Here’s how you do it:

- (IBAction)test:(id)sender {
    // switch back
    
    int controllerIndex = 1;
    
    UITabBarController *tabBarController = self.tabBarController;
    UIView * fromView = tabBarController.selectedViewController.view;
    UIView * toView = [[tabBarController.viewControllers objectAtIndex:controllerIndex] view];
    
    // Transition using a page curl.
    [UIView transitionFromView:fromView 
                        toView:toView 
                      duration:0.5 
                       options:(controllerIndex > tabBarController.selectedIndex ? UIViewAnimationOptionTransitionCurlUp : UIViewAnimationOptionTransitionCurlDown)
                    completion:^(BOOL finished) {
                        if (finished) {
                            tabBarController.selectedIndex = controllerIndex;
                        }
                    }];
}

The controller index is the view you want to transition to (0 based). So you just pick your index, get your from and to view, and then use the transitionFromView method to switch.

Note: You can’t do this from within a viewWillAppear or other lifecyle event. You may get away with it, but it only works once your view is fully loaded.

Helper link:
http://stackoverflow.com/questions/5161730/iphone-how-to-switch-tabs-with-an-animation

How to attach an image from your photo gallery and send it as an image on iPhone

4 Comments

First the easy part. Sending an email to someone in iOS is pretty easy.

You import

#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>

You implement this delegate:

-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    [self dismissModalViewControllerAnimated:YES];    
}

And then you actually send the mail doing something like this:

        // send email
        if ([MFMailComposeViewController canSendMail]) {
            
            MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
            controller.mailComposeDelegate = self;
            [controller setToRecipients:[NSArray arrayWithObject:@"rasmus4200@gmail.com"]];
            [controller setSubject:@"Subject Goes Here."];
            [controller setMessageBody:@"Your message goes here." isHTML:NO];
            
            // Attach an image to the email
            NSData *myData = UIImagePNGRepresentation(coolImage);
            [controller addAttachmentData:myData mimeType:@"image/png" fileName:@"coolImage.png"];
            
            [self presentModalViewController:controller animated:YES];
        }
        else {
            NSLog(@"Device is unable to send email in its current state.");
        }

That’s the easy bit. It’s that middle bit that’s hard. How do you get your hands on the image and then set it as an attachment?

Turns out the way you get your to your photo gallery images is through the ALAssetsLibrary. It’s not enough to just know the URL of your asset on your phone

assets-library://asset/asset.JPG?id=1000000003&ext=JPG

and UIImage from this. You need to do it through the library which looks something like this:

    NSURL *asseturl = [NSURL URLWithString:@"assets-library://asset/asset.PNG?id=656FF2D1-E973-4EDD-9A44-0E8304DBFACC&ext=PNG"];
    
    // create library and set callbacks
    ALAssetsLibrary *al = [EmailViewController defaultAssetsLibrary];
    [al assetForURL:asseturl 
        resultBlock:resultblock
       failureBlock:failureblock];

This setups up the URL of the image you want to get to, as well as the callbacks (blocks) for when the library is ready. They look like this:

    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        UIImage *coolImage;
        
        // get the image
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        CGImageRef iref = [rep fullResolutionImage];
        if (iref) {
            coolImage = [UIImage imageWithCGImage:iref];
        }
        
        // send email
        if ([MFMailComposeViewController canSendMail]) {
            
            MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
            controller.mailComposeDelegate = self;
            [controller setToRecipients:[NSArray arrayWithObject:@"rasmus4200@gmail.com"]];
            [controller setSubject:@"Subject Goes Here."];
            [controller setMessageBody:@"Your message goes here." isHTML:NO];
            
            // Attach an image to the email
            NSData *myData = UIImagePNGRepresentation(coolImage);
            [controller addAttachmentData:myData mimeType:@"image/png" fileName:@"coolImage.png"];
            
            [self presentModalViewController:controller animated:YES];
        }
        else {
            NSLog(@"Device is unable to send email in its current state.");
        }
    };
    
    
    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
        NSLog(@"booya, cant get image - %@",[myerror localizedDescription]);
    };

The magic for getting the image happens here:

        UIImage *coolImage;
        
        // get the image
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        CGImageRef iref = [rep fullResolutionImage];
        if (iref) {
            coolImage = [UIImage imageWithCGImage:iref];
        }

We get the representation of our asset, get it’s original image (fullResolution) and then create a UIImage from that.

With that, we are then free to send in an email. If tested this on gmail and yahoo. Both work. Images come through.

Hears the code in it’s entirety.

EmailViewController.h

#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
#import <AssetsLibrary/AssetsLibrary.h>

@interface EmailViewController : UIViewController <MFMailComposeViewControllerDelegate>
typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);
@end

EmailViewController.m

#import "EmailViewController.h"

@implementation EmailViewController

+ (ALAssetsLibrary *)defaultAssetsLibrary {
    static dispatch_once_t pred = 0;
    static ALAssetsLibrary *library = nil;
    dispatch_once(&pred, ^{
        library = [[ALAssetsLibrary alloc] init];
    });
    return library; 
}




- (IBAction)sendEmail2:(id)sender {

    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        UIImage *coolImage;
        
        // get the image
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        CGImageRef iref = [rep fullResolutionImage];
        if (iref) {
            coolImage = [UIImage imageWithCGImage:iref];
        }
        
        // send email
        if ([MFMailComposeViewController canSendMail]) {
            
            MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
            controller.mailComposeDelegate = self;
            [controller setToRecipients:[NSArray arrayWithObject:@"rasmus4200@gmail.com"]];
            [controller setSubject:@"Subject Goes Here."];
            [controller setMessageBody:@"Your message goes here." isHTML:NO];
            
            // Attach an image to the email
            NSData *myData = UIImagePNGRepresentation(coolImage);
            [controller addAttachmentData:myData mimeType:@"image/png" fileName:@"coolImage.png"];
            
            [self presentModalViewController:controller animated:YES];
        }
        else {
            NSLog(@"Device is unable to send email in its current state.");
        }
    };
    
    
    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
        NSLog(@"booya, cant get image - %@",[myerror localizedDescription]);
    };
    
    
    NSURL *asseturl = [NSURL URLWithString:@"assets-library://asset/asset.PNG?id=656FF2D1-E973-4EDD-9A44-0E8304DBFACC&ext=PNG"];
    
    // create library and set callbacks
    ALAssetsLibrary *al = [EmailViewController defaultAssetsLibrary];
    [al assetForURL:asseturl 
        resultBlock:resultblock
       failureBlock:failureblock];
}


- (IBAction)sendEmail:(id)sender {
    
    if ([MFMailComposeViewController canSendMail]) {
        
        MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
        controller.mailComposeDelegate = self;
        [controller setToRecipients:[NSArray arrayWithObject:@"rasmus4200@gmail.com"]];
        [controller setSubject:@"Subject Goes Here."];
        [controller setMessageBody:@"Your message goes here." isHTML:NO];
                
        // Attach an image to the email
        NSData *coolData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://edibleapple.com/wp-content/uploads/2009/04/silver-apple-logo.png"]];
        UIImage *coolImage = [UIImage imageWithData:coolData];
        
        //        UIImage *coolImage = [UIImage imageWithContentsOfFile:@"assets-library://asset/asset.PNG?id=656FF2D1-E973-4EDD-9A44-0E8304DBFACC&ext=PNG"];
        NSData *myData = UIImagePNGRepresentation(coolImage);
        [controller addAttachmentData:myData mimeType:@"image/png" fileName:@"coolImage.png"];

        [self presentModalViewController:controller animated:YES];
        
        
    }
    
    else {
        
        NSLog(@"Device is unable to send email in its current state.");
        
    }
    
}

-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    [self dismissModalViewControllerAnimated:YES];    
}
    
@end

Helpful links:

http://stackoverflow.com/questions/3837115/display-image-from-url-retrieved-from-alasset-in-iphone

How to add a button to a UITableViewCell iPhone

4 Comments

In the configure cell section of your tableView delete, you can add a button to the cell of your table as follows:

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

    // Configure the cell...
    
        // add friend button
        UIButton *addFriendButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        addFriendButton.frame = CGRectMake(200.0f, 5.0f, 75.0f, 30.0f);
        [addFriendButton setTitle:@"Add" forState:UIControlStateNormal];    
        [cell addSubview:addFriendButton];
        [addFriendButton addTarget:self 
                            action:@selector(addFriend:)
                  forControlEvents:UIControlEventTouchUpInside];
    }

You’ll also need to add an outlet for when someone clicks your button:

- (IBAction)addFriend:(id)sender
{
    NSLog(@"Add friend.");
}

Helper link:
http://stackoverflow.com/questions/8836563/add-button-to-uitableviewcell

Follow

Get every new post delivered to your Inbox.

Join 323 other followers

%d bloggers like this: