Wednesday, July 25, 2012

Working with Action Sheets


Hi,

I got the chance to work on the action sheets.
I created a sample app before going ahead on my project.

Here is what i tried in my sample.
May be someone can be helped with this.

Here you go.....

1) Start with creating a Single View Based Application via 
    Xcode --> New --> Project --> Single View based App



2) Now Open the storyboard, and add a label and a button. clicking on this button the action sheet will be displayed.



3) Now Create an IBAction in .h file and connect the Button's "TouchUpInside"method with the IBAction.





4) Now open the .m file and inside the button's click method create an action sheet.



An important Edit for perfect display of action sheet in landscape mode
    [actionSheet showInView:[self.navigationController view]];
5) Once the action sheet is created we need to add its delegate method also so that we can perform some actions on the buttons added in the action sheet. All the buttons added in the action sheet are identified by their indices.



6) When you RUN the application

7) Click on the "Show Action Sheet" button, You can see the below output.When any button gets clicked in the action sheet then the corresponding delegate method gets fired. We have placed NSLogs inside the method to identify the particular clicks.



Enjoy.....
:)









Thursday, June 21, 2012

Horizontal Scrolling In Table View Cell


Hey guys,

I was very much eager to achieve this functionality.
I got the chance to implement this in iOS 5.0.

I decided to create a sample application before i could start on my project.
Here is the sample for you all.

Have a look...





Step -1  : Create a new Single View Based Application named Scrolling.
               
Step -2  : Open the storyboard and inside the view of your view controller add the following:
                 TableView
                 ScrollView
                 Button
                 Label


Connect the IBOutlets , Datasource , and Delegates of Tableview and the Scrollview.

Step - 3 : FileStructure : 


Step - 4 : Open ScrollingViewController.h and you can see..

a) We have created 3 arrays to store images for 3 rows. This can be done in any way depending upon
     the requirement.

#import <UIKit/UIKit.h>

@interface ScrollingViewController : UIViewController
                                     <UIScrollViewDelegate,
                                     UITableViewDelegate,
                                     UITableViewDataSource>
{
    IBOutlet UIScrollView *imageScrollView;
    IBOutlet UITableView  *tableView;
    IBOutlet UILabel      *textLabel;
    IBOutlet UIButton     *backButton;
    NSArray               *imageArray1, *imageArray2, *imageArray3;
}

@property(nonatomic,retain) UIScrollView *imageScrollView;
@property(nonatomic,retain) UITableView  *tableView;
@property(nonatomic,retain) UILabel      *textLabel;
@property(nonatomic,retain) UIButton     *backButton;

@property(nonatomic,retain) NSArray      *imageArray1;
@property(nonatomic,retain) NSArray      *imageArray2;
@property(nonatomic,retain) NSArray      *imageArray3;

@end

Step - 5 : Open ScrollingViewController.m and add following methods.

a) Inside the viewDidLoad method : We initially show the table view for list and keep the scroll view as 
    hidden for detail purpose.
b) Arrays are initialized here.
c) backButton is also Hidden which gets visible when user clicks on any image in table view.

- (void)viewDidLoad
{
    [super viewDidLoad];
   
    self.textLabel.text=@"Welcome to Table View  with horizontal Row Scroll";
    
imageArray1 = [NSArray arrayWithObjects:@"1.jpeg",@"2.jpeg",@"3.jpeg",@"4.jpeg",@"5.jpeg", nil];
imageArray2 = [NSArray arrayWithObjects:@"11.jpeg",@"12.jpeg",@"13.jpeg",@"14.jpeg",@"15.jpeg", nil];
imageArray3 = [NSArray arrayWithObjects:@"21.jpeg",@"22.jpeg",@"23.jpeg",@"24.jpeg",@"25.jpeg", nil];

    [self.imageScrollView setHidden:YES];
    [self.backButton setHidden:YES];
    [self.tableView setBackgroundColor:[UIColor clearColor]];
    
}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
return 3;
}

d) Inside this method we create the table view cells


- (UITableViewCell *)tableView:(UITableView *)tableView 
                     cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *Identifier=@"Identifier";
    UITableViewCell *cell;
    int arraySize = 0;
    NSArray *arr;
    int offset = 0;

    cell = [self.tableView dequeueReusableCellWithIdentifier:Identifier];

    if(cell == nil)
{
cell = [self reuseTableViewCellWithIdentifier:
                                          Identifier withIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone
}
    switch (indexPath.row)
    {
        case 0:
            arraySize = [imageArray1 count];
            arr = [NSArray arrayWithArray:imageArray1];
            break;
        case 1:
            arraySize = [imageArray2 count];
            arr = [NSArray arrayWithArray:imageArray2];
            break;   
        case 2:
            arraySize = [imageArray3 count];  
            arr = [NSArray arrayWithArray:imageArray3];
            break;
    }

    UIScrollView *scrollview = (UIScrollView*)[cell.contentView viewWithTag:1];

    for (int i=0; i<arraySize; i++)
    {
        UIButton *btn = [[UIButton alloc] init];
        [btn setImage:[UIImage imageNamed:
                        [arr objectAtIndex:i]] forState:UIControlStateNormal];
        [btn setImage:[UIImage imageNamed:
                        [arr objectAtIndex:i]] forState:UIControlStateHighlighted];

        btn.frame = CGRectMake(2+offset, 5, 100, 100);
        btn.tag=indexPath.row*100+i;

        [btn addTarget:nil action:@selector(buttonClicked:) 
                 forControlEvents:UIControlEventTouchUpInside];

        [scrollview addSubview:btn];
        offset = offset+110;
    }
    scrollview.contentSize = CGSizeMake(offset+10, 50);
return cell;
}

e) Here we set the frames.



-(UITableViewCell *)reuseTableViewCellWithIdentifier:(NSString *)identifier 
                                       withIndexPath:(NSIndexPath *)indexPath 
{
CGRect cellRectangle;
cellRectangle = CGRectMake(0.0, 0.0, 340, 180);
UITableViewCell *cell = [[UITableViewCell alloc
                              initWithFrame:cellRectangle reuseIdentifier:identifier];
UIScrollView *scrollview;
cellRectangle = CGRectMake(30.0, 0.0, 280, 95);
scrollview = [[UIScrollView alloc] initWithFrame:cellRectangle];
scrollview.tag = 1;
        scrollview.scrollEnabled=TRUE;
        scrollview.autoresizingMask = TRUE;
    
[cell.contentView addSubview:scrollview];
return cell;
}


f) When user clicks on any image in the table view cell then this method gets called.
    Inside the method we hide the table view and show the scroll view and also change the label text.
    When imageScrollView meant for Detail purpose is shown then we also show the cross button on      
    top right corner to move back to the table view.
    We have used a method  : scrollRectToVisible :  This is used so that when user clicks on 2nd image
    in table view then in detail view by default the 2nd image is shown i.e the scroll view is set to scroll
    to the new position of second image.


-(void)buttonClicked:(UIButton*)btn
{
    [self.tableView setHidden:YES];
    [self.imageScrollView setHidden:NO];
    [self.backButton setHidden:NO];
    self.textLabel.text = @"Detail Scroll View";
    self.imageScrollView.scrollEnabled=TRUE;
    self.imageScrollView.autoresizingMask = TRUE
    
    NSArray *tempArray;
    if(btn.tag>=0 && btn.tag<=4)
        tempArray = [NSArray arrayWithArray:imageArray1];
    else if(btn.tag>=100 && btn.tag<=104)
        tempArray = [NSArray arrayWithArray:imageArray2];
    else if(btn.tag>=200 && btn.tag<=204)
        tempArray = [NSArray arrayWithArray:imageArray3];

    for (int i=0; i<[tempArray count]; i++)
    {
        UIImageView *imageView = [[UIImageView alloc
                      initWithImage:[UIImage imageNamed:[tempArray objectAtIndex:i]]];

        [imageView setFrame:CGRectMake(i*320+10, 5, 300, 300)];

        [self.imageScrollView addSubview:imageView];

        if(btn.tag==i || btn.tag-100==i || btn.tag-200==i)
            [self.imageScrollView scrollRectToVisible:
                                  CGRectMake(i*320+20, 5, 300, 300) animated:YES];
    }
   
    self.imageScrollView.contentSize = CGSizeMake([tempArray count]*320, 310);
    [backButton addTarget:self action:@selector(backbuttonClicked:) 
                     forControlEvents:UIControlEventTouchUpInside];
}

g) When user clicks on the cross button on the top right corner then table view is again visible and 
     scrollview is again set to hidden.


-(void)backbuttonClicked:(UIButton*)backBtn
{
    [self.tableView setHidden:NO];
    [self.imageScrollView setHidden:YES];
    [self.backButton setHidden:YES];
    self.textLabel.text=@"Welcome to Table View  with horizontal Row Scroll";
    [backBtn setHidden:YES];
}





Hope it helps.....






Wednesday, May 30, 2012

Localization in 5.0 - Simplest

Good Evening,

I have been working on localization and was moving around various samples.
Thought i should write one too....
May be it helps someone ;)

Trying to write a simpler one in just 5 steps......

Step : One

Create a new Project in Xcode. In our case its a "Single View Application"


Now save project as : 





Step : Two

Now before going to User Interface part lets add the localization files for different languages.
We will be using English (default) and French

Right click on the project name >> Add New File >> Resource >> Strings File and then do as shown :



Name this file as "Localizable.strings"


Step : Three

By default it accepts English so we need to add another file for French like this:

Click on the Localizable.string file and open "File Inspector"
GoTo Localization section
Click "+" symbol
You can see a list of Apple Languages like this :


Select French from above list . It appears in grey after selection.
Below Image shows how it looks after french gets added up in localization languages for the app.




And after addition you can see files here also:



Step : Four


Contents that we write in these localization file:






Step : Five


Now lets work on UI.
We will add four labels on the view of ViewController and display the contents on it that gets changed as we change the language.

Below image will show how the IBOutlets are connected.



Now whenever you change the language from settings you will see the change is reflected in the app.
The contents get changed :)

How the output appears:




Hope it helps :)

Enjoy coding...........






















Monday, May 21, 2012

Lazy Loading of Images in Table (iOS : 5.0)


Hello all,

I know many of us have successfully done this.
I have tried to show the working via images. Hope it helps all the beginners like me to learn more.

What you can get here:

1) How to start with Story-Boards
2) Url Encoding
3) Lazy loading of images


Here is a tutorial for all,

Step -1 : Open New Project in Xcode :






Step - 2 : Open MainStoryBoard.storyboard

Inside the View add a tableview and connect its DataSource and Delegate with the controller class.
You can also change the background color of the view to have a look like this : 





Step - 3 : Now Open your LazyLoadingViewController.h file and write :


@interface LazyLoadingViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
{
    IBOutlet UITableView            *tableView;
    NSArray                         *animals;
    NSArray                         *animalUrl;
    NSMutableDictionary             *imageDict;
}
@property(nonatomic,retain)UITableView              *tableView;
@property(nonatomic,retain)NSArray                  *animals;
@property(nonatomic,retain)NSArray                  *animalUrl;
@property(nonatomic,retain)NSMutableDictionary      *imageDict;

-(NSString *) URLEncodeString:(NSString *) str;
@end


Step - 4 : Now Open your LazyLoadingViewController.m file and write this : 

a) Synthesize all the properties that you created in .h class
b) Initialize your arrays and dictionary in ViewDidLoad.
       I have done like this : 

    imageDict = [[NSMutableDictionary alloc] initWithCapacity:4];
    animals = [NSArray arrayWithObjects:@"CAT",@"DOG",@"FOX",@"LION", nil];
    animalUrl = [NSArray arrayWithObjects:
         @"http://www.zastavki.com/pictures/1600x1200/2008/Animals_Cats_Small_cat_005241_.jpg",
         @"http://spadogbotanicals.com/wp-content/uploads/puppy1-300x225.jpg",
         @"http://www.nj.gov/dep/fgw/images/wildlife/fox_gl.jpg",
         @"http://www.mikesel.info/wp-content/uploads/2011/07/lion.jpg",nil];


c) Now add all table view methods : 


In our case the number of sections is only one but the rows depend on the total contents in the array we will use to display the contents in the table view


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
return [animals count];
}



d) For cell creation we want to display a default image in the image view till we get the image from server.In our case we have used this :


e) Cell creation is the most important part of the table view  that will display the contents from the web when they are available. This is done via dispatching a background thread that fetches the images in background.



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *Identifier=@"Identifier";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:Identifier];
if(cell == nil)
{
cell = [self reuseTableViewCellWithIdentifier:Identifier withIndexPath:indexPath];
 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone
}
//configure cell
UIImageView *imgView= (UIImageView *)[cell.contentView viewWithTag:IMG_TAG];
if([imageDict  valueForKey:[NSString stringWithFormat:@"%i,%i", indexPath.row, indexPath.section]]==nil)
{
[NSThread detachNewThreadSelector:@selector(displayingSmallImage:) 
            toTarget:self withObject:indexPath];
}
else
{
imgView.image = [imageDict valueForKey:[NSString stringWithFormat:@"%i,%i",
                                          indexPath.row, indexPath.section]];
}
UILabel *lblName = (UILabel *)[cell.contentView viewWithTag:TITLE_TAG];
[lblName setText:[animals objectAtIndex:indexPath.row]];
return cell;
}


-(UITableViewCell *)reuseTableViewCellWithIdentifier:(NSString *)identifier withIndexPath:(NSIndexPath *)indexPath 
{
CGRect cellRectangle;
cellRectangle = CGRectMake(0.0, 0.0, 340, 180);
UITableViewCell *cell = [[UITableViewCell alloc]
                         initWithFrame:cellRectangle reuseIdentifier:identifier];

//here we create the image view and set its properties

UIImageView *img11;
cellRectangle = CGRectMake(15,18, 75, 70);
img11 = [[UIImageView alloc] initWithFrame:cellRectangle];
img11.tag = IMG_TAG;
img11.image = [UIImage imageNamed:@"base-image.png"] ;//acts as default image
img11.contentMode = UIViewContentModeScaleToFill;
[cell.contentView addSubview:img11];
//here we create the label and set its properties

UILabel *labelName;
cellRectangle = CGRectMake(150, 40, 200, 20);
labelName = [[UILabel alloc] initWithFrame:cellRectangle];
labelName.font =[UIFont fontWithName: @"Verdana"size:15.0f];
labelName.textColor = [UIColor blackColor];
labelName.autoresizingMask = UIViewAutoresizingFlexibleWidth;
labelName.tag = TITLE_TAG;
 [cell.contentView addSubview:labelName];

return cell;
}

Note : Remember to add the labels and the image view to the cell's content view.


f) Encode URL : This is done to create verbatim string for url to override the behavior of the escape sequences.

-(NSString *) URLEncodeString:(NSString *) str
{
    
    NSMutableString *tempStr = [NSMutableString stringWithString:str];
    [tempStr replaceOccurrencesOfString:@" " withString:@"+" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [tempStr length])];
    
    
    return [[NSString stringWithFormat:@"%@",tempStr] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}

g) Cell creation is the most important part of the table view  that will display the contents from the web when they are available.If Image is available from the server we will display it else we will display the default image. You can see the test condition for this in BOLD.

After we get the image we save it in the dictionary and display the image on the image view in main thread i.e when the working of background thread is complete.


- (void) displayingSmallImage:(NSIndexPath *)indexPath
{
NSString *imageUrl = [animalUrl objectAtIndex:indexPath.row];
 imageUrl = [self URLEncodeString:imageUrl];
   
NSURL *url = [NSURL URLWithString:imageUrl];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
if(image == nil)
{
image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle
               resourcePath] stringByAppendingPathComponent:@"base-image.png"]];
}
[self.imageDict setObject:image forKey:[NSString
                 stringWithFormat:@"%i,%i",indexPath.row,indexPath.section]];

[self performSelectorOnMainThread:@selector(imageReceived:) 
                        withObject:indexPath 
                     waitUntilDone:NO];
}



h) Here we display the image received and reload the particular row of the table for which we got the image.

- (void) imageReceived:(NSIndexPath *)indexPath

{
UIImage *image = (UIImage *)[imageDict objectForKey:
                             [NSString stringWithFormat:@"%i,%i",
                             indexPath.row,indexPath.section]];
UIImageView *imgs = (UIImageView *)[[tableView
                     cellForRowAtIndexPath:indexPath] viewWithTag:IMG_TAG];
[imgs setImage:image];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                  withRowAnimation:UITableViewRowAnimationNone];
}




i) Don't forget to add this tag in your .m file : This is done so that the labels and image views when created we assign a tag to them so that while giving them their values the same can be accessed via tags.




#define IMG_TAG   1
#define TITLE_TAG 2

This is to be done after the properties are synthesized.

j) You will see output like this : 

  i) When the Application is launched.

ii) When only 2 icons were fetched and rest are in transit


iii) When all icons were fetched from the web server







Enjoy table view and iOS....... :)