Populating Dynamic Table View inside Static Cell - ios

So I'm developing an app where I have to display a table view as the content of a Static table view cell inside a UITableViewController, but I can't seem to populate it with my array.
Because I have two table views inside a UITableViewController, every time I try to add the Controller as it's data source the two tables contents are conflicted.
Does Someone know hot to bypass this?

Actually it is quite possible to have multiple table views using the same view controller as data source. There are many complex layout where this could be useful. To prevent your data from getting mixed up, just check which table view is asking for data in all of the data source methods, for example like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
YourObject *object;
if (tableView == _tableViewNumberOne) {
object = [self.yourFirstArray objectAtIndex:indexPath.row]
} else if(tableView == _tableViewNumberTwo) {
object = [self.yourSecondArray objectAtIndex:indexPath.row]
}
Setup cell ......
}
You need references to the two tableviews from where they were created of course

Related

How show plain picture or plain text when no data available in TableView in objective c?

I have a table view used for showing my favourite video list. if no data available in the table view it will show this.
If you want to show it inside the tableView specifically then you will have to create a cell for the tableView with same structure and handle the cell used made based on wether or not data is present. If no data is present, you will have to instantiate a different cell and when data is present, a different one.
Here is how i would do it instead:
You can initially set the tableView to hidden. And create a view with the required imageViews and labels and also set it to be hidden. Make this view outside and not as the cell. On fetching data, depending on the response, you can unhide one of the views.
Try following code.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (arr.count==0) {
return 1;
}
return arr.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *emptyMessageCellIdenifier = #"emptyMessageCell";
NSString *datacellIdentifier = #"datacell";
UITableViewCell *emptyMessageCell ;
UITableViewCell *datacell ;
if (arr.count == 0) {
return emptycell;
}
else{
return datacell;
}
}
I got the solution.It's so easy. I take a uiview. and when list is empty, hide table view and show that uiview. It's really easy.

UITableView with Multiple Data Arrays

I have an app, in which I have 7 different UITableViewControllers. All 7 are linked through a tabBarController. I am looking for a way to have a single custom class to be used throughout all 7 UITableViewControllers. I have 7 different arrays that all hold a specific number of objects. I need to know how to:
Change the number of rows in the tableView, depending on the array that I'm using as my data source.
Change the array that is being used as the data source based on which ViewController the user is currently looking at (Can this even be done?)
Change the contents of a cell, based on the array being used as the data source.
I'm familiar with using UITableView with a single data source, but I really don't know how to approach it with multiple data sources.
Thanks!
You can have one class be the dataSource for all of the UITableViewControllers
You might implement this by creating a custom subclass of UITabBarController which keeps an array of UITableViewControllers and a corresponding dictionary that maps a UITableVC to the array used by it's data source.
Set that as the data source for all the UITableViews and then handle each dataSource method like my example below.
Take a look at the UITableViewDataSource docs.
All of the methods pass in which tableView they're trying to get information about.
For example:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Here you could compare the tableView var to your array of tableViews to figure out which table view called this
//Based on that you could query your dictionary to find the array that houses the data for that tableView.
//Use the indexPath to find the data that you need to create and return the right cell
}
• Change the number of rows in the tableView, depending on the array
that I'm using as my data source.
You can accomplish this by conditions in tableView delegates
- (NSInteger)tableView:tableView numberOfRowsInSection:section
Inside this delegate you need to identify which dataSource for the particular tableView.
Check the table if its the one being refreshed like so:
- (NSInteger)tableView:tableView numberOfRowsInSection:section
{
if (tableView == self.firstTableView)
return self.firstTableDataSource.count;
if (tableView == self.secondTableView)
return self.secondTableDataSource.count;
//and so on..
}
• Change the array that is being used as the data source based on
which ViewController the user is currently looking at (Can this even
be done?)
Figuring which array you will be using for that particular table is up to you. You can use segement control, buttons, another table, it's up to you.
But the very important part is [tableView reloadData]; at your target table (table that is currently active) and again table delegates will be triggered and you will be doing all the filtering inside those delegates..
while you can check if the viewController is visible by:
if ([self/*viewController*/ isViewLoaded] && self/*viewController*/.view.window)
{
//visible
}
which was already discussed here
• Change the contents of a cell, based on the array being used as the
data source.
This one is not clear.
Is it just the content/values of the subviews of the cell like: cell.textLabel, cell.detailTextLabel and cell.imageView?
or the cell.contentView which is basically, you want to change the look of your cell?
If content/values again you just have to determine which is which, like this (using customCell):
assuming you have a dataSource that looks like:
{
data_source = (
{
text_label = test0;
detail_label = "this is just a text";
image_name = "your_image0.png";
},
{
text_label = test1;
detail_label = "this is just a another text";
image_name = "your_image1.png";
}
)
}
then in the delegate cellForRowAtIndexPath it'll be something like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"tableID";
self.customCell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!self.customCell)
self.customCell = [[YourCustomCell alloc] initWithStyle:(UITableViewCellStyle) reuseIdentifier:cellID];
static NSString *dataSource = #"data_source";
static NSString *textLabel = #"text_label";
static NSString *detailLabel = #"detail_label";
static NSString *imageName = #"image_name";
if (tableView == self.firstTableView)
{
self.customCell.textLabel.text = [self.firstDataSource valueForKey:dataSource][indexPath.row][textLabel];
self.customCell.detailTextLabel.text = [self.firstDataSource valueForKey:dataSource][indexPath.row][detailLabel];
self.customCell.imageView.image = [UIImage imageNamed:[self.firstDataSource valueForKey:dataSource][indexPath.row][imageName]];
}
if (tableView == self.secondTableView)
{
self.customCell.textLabel.text = [self.secondDataSource valueForKey:dataSource][indexPath.row][textLabel];
self.customCell.detailTextLabel.text = [self.secondDataSource valueForKey:dataSource][indexPath.row][detailLabel];
self.customCell.imageView.image = [UIImage imageNamed:[self.secondDataSource valueForKey:dataSource][indexPath.row][imageName]];
}
// and so on...
}
To check all other methods, check apples documentation ,i hope this is useful for you and for others as well.. Happy coding.. :)

Two UITableViews in the same UIViewController

Im trying to have 2 table views on the same view. They both are within the same UIViewController which implementes the UITableViewDelegate and Datasource. one of the tableviews is static and the other is dynamic. The dynamic table view is loading just fine using the methods from its datasource, but the static one is showing up blank. Normally I erase the datasource methods from the controller so the static TableView doesn't override what's already done on the storyboard, but now I can't because those methods are being used by the dynamic TableView.
How can I have both of then under the same controller?
As Putz says, you can set up your view controller to manage 2 table views by setting up your data source and delegate methods to check the table view that's passed in.
However, I don't think you can use static table views with anything but a UITableViewController, and a table view controller only knows how to manage a single table view.
The trick is to add 2 container views to your view controller that will contain 2 table views, and embed a different UITableViewController into each container view. Then each table view is managed by it's own table view controller. I have a project on github that does exactly this: https://github.com/DuncanMC/test
I've set up protocols that the parent view controller and the 2 table view controllers use to communicate, although you don't have to do that if your needs are simpler.
Here is the easiest option, that let's you keep a single VC for your delegate/datasource :
Set both tableviews delegate and datasource to your UIViewController.
Ctrl-drag from one of the static cells to your .h file, and create an IBOutlet collection ( called here staticCellsCollection). Add each static cell to this collection, careful with the order, it will be important.
Implement cellForRowAtIndexPath: this way :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == _dynamicTableView) {
// Do your dynamic thing
}
else if (tableView == _staticTableView) {
// Return the static cells one by one
// Here the static TV has only one section, and all cells are in staticCellsCollection
return staticCellsCollection[indexPath.row];
}
}
You also need to adapt numberOfRowsInSection and numberOfSectionInTableView but this is pretty basic (check which table is asking, and return appropriate values, for example staticCellsCollection.count for the number of rows of the static TV).
You may need to adapt this, for example if you want multiple sections in your static TableView, you should create an IBOutletCollection for each section, and handle the number of rows/sections accordingly, and return the correct cells. Anyway, this is pretty straightforward to implement once you get the idea.
You can have two tableView's use the same delegate functions. It's not amazingly pretty, but you can:
- (UITableViewCell *)tableView:(UITableView *)inTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(inTableView == tableView1)
{
...
}
else if
...
}
Put that type of logic into every tableView delegate function.

How to Initialize my UITableView table to have a certain number of rows based on input from user and a Button

I'm really new to Objective-C here so what I'm asking may be trivial to most of you but any guidance will help.
Here's a picture of my storyboad.
My current objective is to allow for the user to enter in the number of sets (NSInteger *numReps) and then press the "Log Reps" button and have the table initialize with numReps cells that look like the prototype cell.
Now where I'm at a loss for the implementation. I've never done this kind of thing before so I'm not exactly sure what the best way to go about it is. I have thought of making a custom class for the UITableView table that would take info from the view after the Log Reps button is pushed. I'm not entirely sure how this would need to be implemented. Or can I simply add the table to the properties of the view controller and setup the table within the view controller? That was my initial idea and seems ideal so that I would have everything in one place.
Pleas advise. I am new to all of this and come from a C++ background so I'm still learning a lot of the notation.
Try this:
-(IBAction)btnLogClicked {
int iSet = 4 //Number of row in table
UITableView *tblView= [[UITab;eView alloc]initWithFrame:CGRectMake(0,50,320,100)];
tblView.delegate = self;
tblView.dataSource = self;
[self.view addSubView:tblView];
}
Table View Data Source and Delegate Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return iSet;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Display what you want to display in each cell
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
It's not clear what you want to present in your prototype cells, but you need an array (or probably an array of dictionaries) to populate the cells. The number of rows is determined by the number of entires (the count) of that array. So, if you take the number entered by the user, and add that many object to your array, then call reloadData on the table, you will get the number of rows that you want. What those object are that you add to the array, depends on what you're trying to show there.
you could start reading: Table View Programming Guide for iOS
But I can answer you:
You can add the UITableView to the UIViewController, but you need set your UIViewController like the TableView's delegate and dataSource. Your ViewController need to implement the protocol: UITableViewDataSource
The method that you are looking for is: tableView:numberOfRowsInSection:
But I really recommend you that read the Apple Reference.

How to loop through 5 UITableView cells based on the original cell tapped first

I have an app that lists some data in a tableview, in cells. I want the user to be able to select a table view cell, any one, and have the app cycle through the 5 lower cells. Here is what I have so far:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
// Navigation logic may go here. Create and push another view controller.
[self fetchCellsToProcess:indexPath];
}
Here is the fetchCellsToProcess: method:
-(void)fetchCellsToProcess:(NSIndexPath*)indexPath{
for (int cellsToProcess = 0; cellsToProcess < 5; cellsToProcess++) {
//process each cell
//...
}
}
I need use the indexPath to get its indexPath.row. Then add 5 to that indexPath.row and only process the tweets between indexPath.row passed in and indexPath.row+5. What programming logic should I use to cycle through cells x -> x+5?
You should not be using cellForRowAtIndexPath: here: that's part of the presentation logic, while you are working on the model-level logic here.
Look at your cellForRowAtIndexPath: method, and see from where does the text of the cell's labels come. Usually it is an NSArray or some other collection. Your didSelectRowAtIndexPath: method should go directly to that same collection, and grab the info from there.
There is no direct approach to achieve this as dasblinkenlight mentioned
but there is a work around which works for me.
Please follow below approach:
Create your custom button within your custom cell
Create your custom cell class and put button(change type to custom ) do necessary connection custom cell class
create and connect action method named "actionSelectedCell" as below from that button in class you are implementing this logic.
And cellForRowAtIndexPath cell.customButton.text = data from your array or dictionary
- (IBAction)actionSelectedCell:(UIButton *)sender {
// below code for getting selected cell row and its section
UIView *view = sender.superview;
while (view && ![view isKindOfClass:[UITableViewCell self]]) view = view.superview;
UITableViewCell *cell = (UITableViewCell *)view;
indexPathForSelectedCell = [self.tableViewListViewVC indexPathForCell:cell];
NSLog(#"cell is in section %d, row %d", indexPathForSelectedCell.section, indexPathForSelectedCell.row);// so now you are getting indexpath for selected cell
// now you can create simple loop logic to get required data and do whatever you like post it to something or store it for any other use
NSString *strFifthCellContent = [NSString stringWithFormat:#"%#",[dataArray ObjectAtIndex:indexPathForSelectedCell.row+5]]; // in this way you can get data from any cell
}

Resources