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.....