Yury
Yury

Reputation: 6114

How better implement UITableView with two "tabs"?

Both tables must be in one view controller, switching by segment control for example. Data is infinite, fetched from core data. I see three solutions:

1) create two objects of UITableView and filling them in shared datasource functions; keeping one of tableviews hidden

2) create two view controller containers, embed in main view controller, and perform completely separated data source methods; keeping one of containers hidden

3) use only one table view object, reloading data when needed, providing offset saving

Need your opinions. Which solution will be faster and/or more readable and right?

Update

Let me try to implement third option:

var tableViewOffsets = [Int: CGPoint]()

func segmentValueChanged(sender: UISegmentedControl) {
    tableViewOffsets[tableView.tag] = tableView.contentOffset
    tableView.tag = sender.selectedSegmentIndex
    tableView.reloadData()
    if let savedOffset = tableViewOffsets[tableView.tag] {
        tableView.setContentOffset(savedOffset, animated: false)
    }
}

func tableView_dataSourceMethodsTemplate(tableView: UITableView, ...) {
    if tableView.tag == 0 {
        //perform data source code for first tab
    } else {
        //perform data source code for second tab
    }
}

Upvotes: 7

Views: 1595

Answers (4)

Stefan
Stefan

Reputation: 1335

I think that the handling one table view with two arrays depending on segmented control is maybe the best option. I would add one bool that will handle which segment index is, for example isZero. Just create one UISegmentedControl and action for handling indexes. Note: I will add objective-c code, but I think you will recognize concept.

-(IBAction)segmentChangeViewValueChanged:(UISegmentedControl *)segmentedControl
{
    if (segmentedControl.selectedSegmentIndex == 0) {
        self.headerLabel.text = @"Contacts";
        self.searchButton.hidden = YES;
        self.isContactsSegment = YES;
        self.searchTextField.text = @"";
        self.refinedContactsSearch = [NSMutableArray arrayWithArray:self.contacts];
        [self.contactsTableView reloadData];
    }

    else {
        self.headerLabel.text = @"Search on server";
        self.searchButton.hidden = NO;
        self.isContactsSegment = NO;
        self.searchTextField.text = @"";
        [self.contactsTableView reloadData];
    }


}


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

    ContactsTableViewCell *contactCell = (ContactsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"contactCell"];
    ContactsModel *model = [[ContactsModel alloc] init];
    if (self.isContactsSegment == YES) {
        model = self.refinedContactsSearch[indexPath.row];
    }
    else {
        model = self.serverContacts[indexPath.row];
    }

    if (contactCell == nil) {
        contactCell = [[OTContactsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"contactCell"];
        contactCell.backgroundColor = [UIColor clearColor];
        [contactCell.contactLabel setTextColor:NEON_GREEN];
        [contactCell setSelectionStyle:UITableViewCellSelectionStyleNone];
        [contactCell.separator setBackgroundColor:[self.contactsTableView separatorColor]];
    }
    contactCell.contactLabel.text = [NSString stringWithFormat:@"%@ %@", model.name, model.surname];
    [contactCell.contactLabel sizeToFit];
    [contactCell.contactImage setImageWithURL:[NSURL URLWithString:model.pictureUrl] placeholderImage:[UIImage imageNamed:@"Logo"]];
    contactCell.contactImage.layer.cornerRadius = contactCell.contactImage.frame.size.height/2;
    contactCell.contactImage.layer.masksToBounds = YES;



    return contactCell;
}

Upvotes: 1

Anbu.Karthik
Anbu.Karthik

Reputation: 82759

option number third is easy and good memory optimize also, in my suggestion use tag Concept with single tableView if you selected the any segment assign the tag for your tableview (e.g yourtableview.tag = 1) and at the same time change the frame what ever you need,

Updated

func segmentValueChanged(sender: UISegmentedControl) {
tableViewOffsets[tableView.tag] = tableView.contentOffset
tableView.tag = sender.selectedSegmentIndex
var tablearray = [string]()
 if sender.selectedSegmentIndex ==  0
{
  // here fecth the value in coredata and append in array
 tablearray.append (yourdta)
 }else
  {
  // here fecth the value in coredata and append in array
    tablearray.append (yourdta)
  }


if let savedOffset = tableViewOffsets[tableView.tag] {
    tableView.setContentOffset(savedOffset, animated: false)
}
tableView.reloadData()
}

func tableView_dataSourceMethodsTemplate(tableView: UITableView, ...)    {
 return tablearray.count
}

Upvotes: 5

Raj Aggrawal
Raj Aggrawal

Reputation: 761

  1. You need to create two data source array for both the tabs 2.Load tableview when tab changes.
  2. in cellforrowatindexpath you need to handle the showing data from data source array for the selected tab.

ie. You can handle both tab with single table view.

Upvotes: 1

Vishal Sonawane
Vishal Sonawane

Reputation: 2693

You can opt third solution. You can use UISegmentedControl to work as your tabs and on selecting segment you can assign datasource to same tableView.This will also reduce memory use as you will use single tableView and it will be preloaded for use as second tableView.

Upvotes: 1

Related Questions