UISegment Control in UITableView - iphone

I have added a segment control to my table view and what my problem/question is I need to display text in tableview cells based on segment selected.
I have followed some tutorials, in that they gave me text in labels based on segment selected. I used segmentControl.selectedIndexPath also. So can anyone tell me how can we set that array of objects to my tableview cells based on segment selected?
Correct me if any mistakes in my english.
Please help me.
Thanks a lot for help.

First of all you have to divide your data in different arrays depends on your requirement ie Number of segmentControl.
Here if there are three segment controls then create three array an in the table view's delegate methods depending on segment control's selected index change the array to display in table view.
Like if segmentControl.selectedIndex == 0 then array1 if == 1 then array2 and if == 2 then array3.
In all delegate and datasource methods of table view. And on segment control's selecedIndexChange: method call reload table.
Happy Coding :)
EDIT 1
For change data in table view on segmented control's index change you must have one IBOutlet for tableView and use that IBOutlet to change the data using [tableView reloadData]; here tableView is IBOutlet for table view.
Happy Coding :)

Common use for tableview;
In Controller you have an array which has the objects, lets say _tableObjects
You have implemented in your controller datasource methods
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =......
.................
cell.labelText.text = [_tableObjects objectAtIndex:indexPath.row].name;
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _tableObjects.count;
}
So if it is like this, you can change _tableObjects array in somewhere in you code.
_tableObjects = myOtherArray;
[self.tableView reloadData];

Related

How to prevent TableViewCell from duplicating during recycle?

So my situation is pretty unique. I have a to-do list app with a bunch of tasks. Each task has a UITableViewCell. After each table view cell is tapped, it creates a view controller with the task at that row's index path's property. These view controllers are all stored in a NSDictionary. This is the code representation of what I just said:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
DetailViewController *detailVC;
if (![self.detailViewsDictionary.allKeys containsObject:indexPath]){
detailVC = [[DetailViewController alloc]initWithNibName:#"DetailViewController" bundle:nil];
[self.detailViewsDictionary setObject:detailVC forKey:indexPath];
detailVC.context = self.managedObjectContext;
}else{
detailVC = self.detailViewsDictionary[indexPath];
}
Tasks *task = [[self fetchedResultsController] objectAtIndexPath:indexPath];
detailVC.testTask = task;
[[self navigationController] pushViewController:detailVC animated:YES];
NSLog(#"%#", self.detailViewsDictionary);
}
So this method of creating unique view controllers and storing them with a certain key almost always works. The problem arises when I delete or move the view controllers:
I was under the impression that a cell's index path gets recycled as you scroll down (dequeue). Doesn't that mean marking each cell with a number identifier would result in multiple cells for the same identifier?
Also, if you stored each view controller with a indexPath key, how do you make sure the key isn't set to two view controllers..? For example. Let's say you have 4 cells, which means 4 view controllers. You delete cell 3. Cell 4 moves down to cell 3s spot. You create a new cell which goes to spot 4. Now you have two controllers with the same indexPath key! How do you avoid this?? It's screwing up my app right now because tasks that have already been moved are loading their properties in the wrong view controller/cell!
I was suggested this to solve the problem before: "You maintain an NSMutableArray that "shadows" the contents of the table." However, I don't understand what this means/how to implement it.
You can use a technique we used to use on old databases. You store an NSInteger as a class var, and use that to assign a unique id to each of the cells as you create them. As you create each cell, you increment the unique id. Like this:
in your interface:
#property (nonatomic, assign) NSUInteger nextUniqueId;
then in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
cell.tag = self.nextUniqueId++;
and then track those tags in your viewControllers. Just give them an assignable property, or customize the init to include the id.
Better to set the tag value for each row in cell for row at index path method.Store that tag value globally,and use that tag in did select row method.

Troubles with datasource and tableviews

I've got an UIViewController with 2 tableviews:
1- the main tableview, which is shown in the whole view controller
2- the second viewcontroller, which is loaded in a popup view.
The second tableview is shown on swiping a cell of main tableview.
Depending on which cell is swiped, there are different data in popup view.
I've already loaded the whole data in viewdidload method and stored everything in nsmutablearray, so are ready to be loaded.
My problem is that I don't know how to work with tableview's DataSource, in my project i linked both tableview's datasource to file's owner, but in this way it loads the numberofrows from the main view, and it doesn't take the correct count which should have the second tableview.
So, if in main tableview i have for example 3 elements, and in the second tableview it should load 5 elements, it gives me an error, ('NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index…).
I think that i should link my tableviews to different datasource, even if i really don't know.
I hope to be clear, if you need more info, or a better description, ask me and i'll do it for you.
In the delegate method, you should compare the tableview.
See the example,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView == maintableView)
return VALUE_FOR_MAIN_TABLE_DATA;
else
return VALUE_FOR_POP_TABLE_DATA;
}
No Problem
you just set tags to your tables.
[tableView1 setTag:1];
[tableView2 setTag:2];
and then
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView.tag == 1) {
return 4;
}
else if (tableView.tag == 2)
{
return 5;
}
}
do similar thing all data source method
You can use one View Controller as an unique data source for multiple table view, but you'll need to check which table view is requesting data using the tableView arguments of the UITableViewDataSource methods.
For example:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.mainTableView)
{
// code for your main table view
}
else
{
// code for your popup table view
}
}
The same instance of a view controller serving as data source/delegate for two tables is technically possible but has a number of traps. One of these is: to which of the two tables does self.view refer?
However, most of the data source protocols hand down a reference to the table. You could use that rerference to determine which table acutally sends the request. But not all methods of the protocol inclulde a reference to the table. And that is where it starts getting tricky.
You are far better off with two distinctive view controllers, one for each table. Establish a protocol between them so that the main view controller can hand down the data to the one in the popup window so that the popup can initialize/load it self with the proper data and can refresh its view when ever the data changes.
You will need to check for the tableview in all your delegate and datasource methods as follows:
if (tableView == mainTable)
{
// code for your main table
}
else if (tableView == popupTable)
{
// code for your popup table
}
You do same for 2 or more table views.
Hope this helps.
You can do it both ways:
Make separate classes as data source for separate tables. Instantiate their objects as datasources for tables and bind them at viewDidLoad method in proper view controller.
Make one datasource for 2 tables which I don't recommend as it is not comply with proper OOAD. You'll have tight coupling this way between view controller and the table which can be cause of trouble in the near future.
You have method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
in which you can distinguish to which table you are referring:
if (tableView == mainTableView) {
// initialize cell for main table view
}
if (tableView == secondTableView) {
// intialize cell for second table view
}

How to make two custom tableviews that works like a 2 rows uipickerview

I created a uiscrollview and add a uitableview as subview. I use this class to create two scrollivew each has added a tableview inside it. I want these 2 tableview works like uipickerview which has 2 rows in it. When I click a uitableviewcell on the left, the other tableview should reload it's data to match the selection. Just like a uipickerview, when click a item in row 0, row 1 updates it's data. I want to implement this functionality in tableview, the only difference is that i click the cell in tableview, not scroll item like uipickerview.
You need to keep reference of two tableViews, two seperate dataSource array. And when the mainTableView is selected, form the dataSource of the second tableView and reload it.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.tag == 1) //Main TableView
{
//Form the dataSource of the second tableView
//You need to have a logic to form this array
//from the selected indexPath of main tableView
self.secondDataSourceArray = ...
[self.secondTableView reloadData];
}
}

How do I populate a predefined UITableView to a view using the interface builder

I've created a custom UITableViewCell with a label and a text field.
I want to create two cells in a group to represent a nice username/password input mechanism.
I've run into some troubles figuring it out (things like the delegate/dataSource).
Is there a more direct approach to just add those two cells and get the data inserted into the text fields from code?
P.s. I want the TableView to be only at a part of my screen, the other part will be an "Enter" button...
Plus, if it can do it via the interface builder that would be great.
Although I agree with jer, some pointers about how to still use IB to make table view cells.
Add the cells to your NIB (at root level) and make them look good. Add two IBOutlet UITableViewCell *cell0, *cell1; to your header. Hook up the cells in the NIB to these outlets.
In the class which is your dataSource, do something like:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch ([indexPath row])
{
case 0: return cell0;
case 1: return cell1;
}
NSLog("Something bad happened");
return nil;
}
Interface builder doesn't know about your table view data. If you are confused about setting up a data source, then read the documentation, try the sample code, explore until things make sense. Ask when you get frustrated.

editingStyleForRowAtIndexPath Scrolling problem

I am facing a very strange problem with editingStyleForRowAtIndexPath method. I am planing to change the appearance of editable cells. It was working fine, but when i scroll the table i am not getting the table cell pointer in the editingStyleForRowAtIndexPath delegate method. So the new cells does not get the custom appearance.
I am using this -
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
// get tablviewcell pointer
UITableViewCell* pCell = [tableView cellForRowAtIndexPath:indexPath]; // <- not getting the pointer when scrolling the table and new cells come up
//Changin cell appearance here ...
}
Thanks in advance!
I think the table view may call this method before it assigns a cell to the given index path. A more reliable way to customize table view cells would be to override -tableView:willDisplayCell:forRowAtIndexPath:. You can test the cell's editingStyle property there and act accordingly.