Tuesday, March 2, 2010

UIAlertView with UITextField (AlertView with TextBoxes)

We can have custom AlertView with TextFields (TextBoxes) so user can enter the data into it.

Things to consider are:

1) Declare TextField in Header file; this helps in fetching the value of TextField in other functions.

2) Allocate & Initialize TextField; and add it as SubView to AlertView object.

3) use CGAffineTransform to move the AlertView object to top so that virtual keyboard, don't overwrite it.

4) You can fetch the values of TextField in the function

- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex


Business Scenario: This type of functionality is used to prompt user for entering credentials like logging details:


//Create a custome UIAlertView with TextFields & Buttons

UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:@"Twitter Login" message:@"\n\n\n\n" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Sign In",nil];

UILabel *lblUserName = [[UILabel alloc] initWithFrame:CGRectMake(20, 55, 65, 21)];

lblUserName.tag =2;

//lblUserName.backgroundColor = [UIColor darkGrayColor];

lblUserName.font = [UIFont systemFontOfSize:12.0];

lblUserName.text = @"User Name:";

[myAlertView addSubview:lblUserName];

if(txtTwitterUserName == nil)

txtTwitterUserName = [[UITextField alloc] initWithFrame:CGRectMake(89, 50, 160, 30)];

//txtUserName.tag = 3;

txtTwitterUserName.borderStyle = UITextBorderStyleBezel;

txtTwitterUserName.textColor = [UIColor whiteColor];

txtTwitterUserName.font = [UIFont systemFontOfSize:12.0];

txtTwitterUserName.placeholder = @"Twitter User ID";

[myAlertView addSubview:txtTwitterUserName];

UILabel *lblPassword = [[UILabel alloc] initWithFrame:CGRectMake(20, 95, 65, 21)];

lblPassword.tag = 4;

//lblPassword.backgroundColor = [UIColor darkGrayColor];

lblPassword.font = [UIFont systemFontOfSize:12.0];

lblPassword.text = @"Password:";

[myAlertView addSubview:lblPassword];

if(txtTwitterPassword == nil)

txtTwitterPassword = [[UITextField alloc] initWithFrame:CGRectMake(89, 90, 160, 30)];

txtTwitterPassword.borderStyle = UITextBorderStyleBezel;

txtTwitterPassword.textColor = [UIColor whiteColor];

txtTwitterPassword.font = [UIFont systemFontOfSize:12.0];

txtTwitterPassword.secureTextEntry = TRUE;

txtTwitterPassword.placeholder = @"Password";

[myAlertView addSubview:txtTwitterPassword];

//Transform to move AlertView up to show keyboard

CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0.0, 130.0);

[myAlertView setTransform:myTransform];

[myAlertView show];

[myAlertView release];



Other method to read which button was pressed.

- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex

{

NSLog(@"%d", (int) buttonIndex);

if (buttonIndex == 1)

{ // Sign-In pushed

[MGTwitterEngine setUsername:txtTwitterUserName.text password:txtTwitterPassword.text remember:YES];

NSString *messageBody = @"This is 2nd March: ";

_twitter = [[MGTwitterEngine alloc] initWithDelegate:self];

NSString* mgTwitterConnectionID = nil;

mgTwitterConnectionID = [_twitter sendUpdate:messageBody];

}

else

{

// Cancel pushed

}

}


Tuesday, February 23, 2010

Fetching iPhone Application version number

To fetch iPhone application version number from info.plist

NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];

Wednesday, January 20, 2010

Barcode Reading

We can read the Barcode using Vision Smarts Barcode reader library.
http://www.youtube.com/watch?v=jNDu0Rb0vRY

Navigating from 1st page to 2nd page

Code if we have NIB file

SecondPageViewController *secPgViewCtrl = [[SecondPageViewController alloc] initWithNibName:@"SecondPageView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:secPgViewCtrl animated:YES];
[secPgViewCtrl release];

Thursday, July 23, 2009

Info Button

Increase the touchable area on the Info button, so we can easily press.

CGRect newInfoButtonRect = CGRectMake(infoButton.frame.origin.x-25, infoButton.frame.origin.y-25, infoButton.frame.size.width+50, infoButton.frame.size.height+50);
[infoButton setFrame:newInfoButtonRect];

iPhone Image Orientation

One of our main focus when we started to write Sketches was to leverage as much as possible the existing technologies already available in the iPhone. This is not a new idea: just as all Mac OS X apps cooperate with each other, we thought that integrating Sketches with the rest of apps in the system would make it a far more fun and pleasing app.

Given the complete lack of documentation or experience, trying to figure out how the APIs work and fit together with each other was no easy endeavor. However, we bravely set out to study the Cocoa iPhone APIs, armed with our previous knowledge of desktop Cocoa, and a lot of patience. Sometimes we thought the effort might be overkill, but being perfectionists at heart, we were uneasy to deliver something that we ourselves considered suboptimal. We are satisfied with many of the results we got, and people seem to appreciate them too. In fact, we've had several fellow coders ask us about details in our image handling code, or how we manage to send emails from Sketches without actually launching MobileMail.

One of the areas we are frequently asked about is the way we handle images shot from the camera or picked from the photo album, and how we detect their orientation. Instead of answering the questions privately, we thought it could be interesting for others to post them here. Maybe our explanations will become outdated next week after The Event - if so, that'd be great news for all :)

In the following paragraphs I'll try to describe some of the interesting "features" I found when guessing how to use the Camera and Photo Album APIs, with a special focus on detecting orientation. I may be utterly wrong in my interpretations, but so far they have been working reasonably well for Sketches :)

* Warning: technical burble ahead *

The first idea that comes to mind if you want to have the camera shoot pictures and use them in your app, is to use the cameraController:tookPicture:withPreview:jpegData:imageProperties callback invoked by the CameraController class. It looks promising, but after some experimentation, we found this approach was not as flexible as we required. Instead, we are using a different mechanism in Sketches. We subscribe to the CameraImageFullSizeImageReadyNotification event, which is sent just after a new photo has been taken. Early in our development we decided to subscribe to all notifications and log them in a file, a simple technique that was instrumental to learn about the existence of this particular notification. In our code, the method that receives the notification is similar to the following:

- (void) cameraImageFullSizeImageReadyNotificationObserver: (NSNotification *) notification
{
NSLog( @"cameraImageFullSizeImageReadyNotificationObserver" );
[cc stopPreview];
CameraImage * cameraImage = (CameraImage *) [notification object];
if ( cameraObserver && [cameraObserver respondsToSelector: @selector(imageWasSelected:)] )
{
[cameraObserver performSelector: @selector(imageWasSelected:) withObject: cameraImage];
}
}


The important piece of information here is that the "object" property of the notification contains an instance of the CameraImage class, which belongs to the PhotoLibrary API framework. In a moment we'll show how to deal with CameraImage instances.

For photos picked with the photo album browser, we use the PLUIController class. A line like

[[PLUIController sharedInstance] setDisplayingPhotoPicker: YES];

will trigger selection of a photo from the photo album. If you set a delegate object, the photo album will invoke your delegate's imageWasSelected method, indicating as a parameter the CameraImage instance that corresponds to the image selected. Note we are using the shared PLUIController instance and do not instantiate a copy ourselves - results are more difficult to achieve the other way around, because the constructor of the shared object actually knows how the instance has to be instantiated, while we have no idea about the properties we should set to make it work.

Therefore, for both types of photo selection (shooting with the camera or selecting a photo from the photo album), we end up with a CameraImage instance to deal with. A CGImage can be created from the CameraImage, using the following API call:

int orientation;
struct CGImage * cgimage = [image createFullScreenCGImageRef: &orientation];

Now we have a Core Graphics image, which is a good thing because there's actually a whole lot of documentation about that.

However, this is where things get a bit hairy regarding how to determine image orientation.

First of all, there are three different sets of values that refer to orientation characteristics:

- If you copy photos from your iPhone to your computer and look at them in an EXIF browser, you'll see that they contain one of the following values: "1" for "normal" images; "3" for images that are rotated 180 degrees; "6" for images that are rotated 90 degrees; and "8" for images that are rotated 90 degrees counter-clockwise.
- The orientation value returned in the integer above does not correspond to the EXIF values just mentioned. The values returned by createFullScreenCGImageRef are, respectively: "1", "2", "3", "4". To make things amusing, images shot with your phone in the vertical upright position will typically be stored to disk with a 90 degrees CCW rotation; therefore, the orientation value you'll receive if you pick such a photo from the photo album will be "4".
- Third, the device orientation, as reported by UIHardware, uses a different set of values. They are the following: "1" (phone vertical, upright position); "2" (phone upside down); "3" (phone rotated 90 degrees CCW with respect to the vertical position); "4" (phone rotated 90 degrees CW).

Therefore, after you select a photo from the photo library, you should check the orientation value you get when creating the CGImage reference, and then you have to correct the rotation using the rotation and translation transformations provided by the CoreGraphics API.

For photos shot with the camera, however, the orientation value returned by createFullScreenCGImageRef at that particular callback is always "4", no matter what the device orientation is, or the way the photo is stored in the disk. This probably happens because my initialization of the camera related APIs is possibly incomplete, but I haven't figured out how to achieve a better result. For shots, therefore, what we do is use the device orientation value, then rotate the photos according to the description above.

Another option I tried was to open the physical files that refer to the CameraImage and read their properties. I was hoping to get the EXIF orientation value, but it seems that at this stage not many properties are available. In fact, code like the following yields a dictionary with just a "FileSize" property:

NSString * imgPath = [[image fileGroup] pathForFullSizeImage];
CGImageSourceRef imageSource = CGImageSourceCreateWithURL( (CFURLRef) [NSURL fileURLWithPath: imgPath], NULL );
NSDictionary * imageProps = (NSDictionary *) CGImageSourceCopyProperties( imageSource, NULL );

Creating Image - Photo Slideshow / iPhone Photo Album

Code to show images / photos in slide show as Photo Album using iPhone SDK / Cocoa / XCode:

NSArray *myPhotos = [NSArray arrayWithObjects:
[UIImage imageNamed:@"Photo1.gpeg"],
[UIImage imageNamed:@"Photo2.gpeg"],
[UIImage imageNamed:@"Photo3.gpeg"],
[UIImage imageNamed:@"Photo4.gpeg"],
nil];

UIImageView *myPhotoAlbumView = [UIImageView alloc];
[myPhotoAlbumView initWithFrame:[self bounds]];
myPhotoAlbumView.animationImages = myPhotos;
myPhotoAlbumView.animationDuration = 30; //Duration in seconds
myPhotoAlbumView.animationRepeatCount = 0; //0 (Zero) indicates infinite loop
[myPhotoAlbumView startAnimating];
[self addSubView:myPhotoAlbumView];
[myPhotoAlbumView release];

--Mitesh Mehta
miteshvmehta@gmail.com

Image Display

To display an image on iPhone / iPod application developed using XCode, but without using UI Builder; i.e. manually writing code to display image:

CGRect myImageRect = CGRectMake(0.0f, 0.0f, 150.0f, 80.0f); //This will create rectangle object to place image with start & end positions
UIImageView *myImageView = [[UIImageView alloc] initWithFrame:myImageRect];
[[myImageView setImage:[UIImage imageName:@"myPhotoImage.png"]]; //Specify the name of image file with path
myImageView.opaque = YES; //Set the properties for image -- opaque,
[self.view addsubView:myImageView]; //Display the image
[myImageView release]; //Release the image object from memory

The above example is for showing image in rectangle, we can also show image in circle shape or any other custom shape.

-Mitesh Mehta
miteshvmehta@gmail.com

Logging

Code to write application log in iPhone SDK / Cocoa using XCode :

NSLOG(@"log : %i", myIntVariable); //Log values of Integer variables
NSLOG(@"log : %f", myFloatVariable); //Log values of Float variables
NSLOG(@"log : %@", myStringVariable);//Log values of String variables

In XCode logging values can be viewed from Console window; it is availbale in XCode @ RUN --> CONSOLE.

--Mitesh Mehta
miteshvmehta@gmail.com

Alert Message

Code to showing Alert message with OK button using iPhone SDK / Cocoa programing:

UIAlertView *alert = [[UIAlertView Alloc]initWithTitle:nil message:@"An Alert message!" delegate:self cancelButtonTitle:"OK" otherButtonTitle:nil];
[alert show];
[alert release];

--Mitesh Mehta
miteshvmehta@gmail.com