Apologies if this question is a little basic but I've spent several days trying to understand the root cause of this problem without any success.
I am working on an app which relies heavily on UITableView objects. I can successfully use a UITableViewController object and display information in a table but I need to be able to have multiple tables on screen citing data from multiple sources and the UITableViewController seems to be too limited.
I would like to be able to place multiple UITableView objects with the storyboard then create custom class files which manage the tables. Unfortunately when I've tried this, XCODE doesn't let me select these custom classes to manage the tables.
Although I've found some potential workarounds online I want to understand why selecting a new class to govern a table view is not possible.
[I wanted to post images but apparently I can´t until I have a better reputation...]
It depends on exactly what you did. But, you should really take a different approach:
If you can, use a single table view with multiple sections (with headers / footers).
If you can't do that, create a separate table view controller and table view for each section of information that you want. Then, your 'main' view controller should act as the parent and add all of the other table view controllers as children (addChildViewController:) and their views as subviews. This approach will keep your code segregated and organised rather than trying to have one controller manage many disparate views.
.h
{
UITableView *objlefttableview;
UITableView *objrighttableview;
}
.m
viewdidload
{
if(!objlefttableview)
objlefttableview=[[UITableView alloc]initWithFrame:CGRectMake(0, 87, 227, 681) style:UITableViewStylePlain];
if(!objrighttableview)
objrighttableview=[[UITableView alloc]initWithFrame:CGRectMake(227, 87, 263, 681) style:UITableViewStylePlain];
[objlefttableview registerNib:[UINib nibWithNibName:#"View" bundle:Nil] forCellReuseIdentifier:#"leftCell"];
[objrighttableview registerNib:[UINib nibWithNibName:#"ViewR" bundle:Nil] forCellReuseIdentifier:#"rightCell"];
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self->objlefttableview==tableView)
{
}
else
{
}
}
so what i just did is i created two tableview objects and then i gave two different custom cell to both of them
If u need more help in this approach do ask
The problem was that where as the UITableViewController object is by default the UITableView delegate and it's datasource, a UIView is not even if it inherits from UITableViewController. I hadn’t specified that and it seems that neither 1 nor multiple tables could function as they had no class governing them set to be delegate and data source.
By specifying in the ViewController’s .h file that it was also the delegate and datasource for the UITableView like below (the delegate and datasource commands should be surrounded by triangle brackets but they aren't displayed on this for some reason):
#interface DHViewController : UIViewController [UITableViewDataSource, UITableViewDelegate]
and in the .m file’s viewDidLoad method specify that it was the data source and delegate for both tableViews like so:
self.tableAnswers.delegate =self;
self.tableAnswers.dataSource = self;
self.tableQuestions.delegate =self;
self.tableQuestions.dataSource = self;
and implementing the necessary methods in the .m file:
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
…both tables can be independently managed and displayed on the same screen.
Thanks a lot to all for your help!
FYI (I think I will still go for #Wain ’s idea of having a single table with section specific content/behaviour - it seems much neater).
1) Add UITableView for your storyboard.
2) Set delegate and data source.
3) Create Outlets (properties in your class) for those tableView's
Then you can work with thouse table views. For example, place label on it, and change it text dynamically in your programm.
Cheers :)
Related
I have created numerous Xcode projects to see if this was a single project problem but no. The problem that I am getting is that when I populate a UITableVIiew with either local data or data that is stored in a Parse database it does not show.
I have tried re-installing Xcode, cleaning my project and walking through the code/project to see if I'd made a mistake but everything looks in place.
An example is that I created a UITableViewController with a UIImage in the cell and when I build and run the project it does not show up.
Here is an example:
Thanks in advance.
You should implement two required methods of UITableViewDataSource.
Something like that:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
return cell;
}
This would go quicker if you just posted the available code... Annnnyway...
The reason I ask is because if you've only done this in storyboard, and it's a dynamic table, the table looks to your numberOfRowsInSection method to see if it should be populating the table or not. If this is 0, then you'll get no rows no matter what you put into the storyboard.
Also, if you've got a cell identifier of cell in your cellForRowAtIndexPath, but you haven't identified your storyboard cell as cell, then you'll still get blank cells.
Furthermore, if you have implemented these two methods correctly, you need to ensure that this table is hooked up to that class as it's dataSource, either via storyboard or programatically.
But these are all just guesses because I would need to see code to figure it out.
If you are using a UITableViewController, have you changed the cells to static?
You said you don't have any custom code other than what Xcode provides. That is your problem.
You need to implement the UITableViewDataSource methods in order to install your data into your table view. Xcode does not do that. The code Xcode puts into your view controller tells the table view that there is no data. You need to report that there is at least 1 section, and at least 1 row in that section. You then need to write code for cellForRowAtIndexPath that installs data from your model into your cells.
Nikita lists 2 of the 3 methods that you must implement before you table view will do anything.
I am trying to set up a UITableView inside of a UIViewController. I'm doing this because it allows me to add a top bar with save and cancel buttons. I'm using storyboard and static cells to model the tableview to get input from the user (think of the create new event in Apple's calendar app). I have the view in Xcode, but when running it on my phone or the simulator, the tableview does not display. Here is the simple view in Xcode:
And this is how it displays when running it:
I've read about adding delegates and setting the datasource and such, but really this is all just going to be static cells with text fields, no data being loaded. Why is this happening and what can be done to fix it? Thanks!
#Made2k It looks like you found a solution, but for others who come across this with the same issue, note that you can only use a UITableView with static cells inside of a UITableViewController. This is not a well-documented fact, but apparently only UITableViewController knows how to handle the layout of static cells, whereas a regular UIViewController just needs to implement the UITableViewDelegate and UITableViewDataSource protocols in order to handle display of content in a UITableView added either programmatically or via Storyboard/Nib.
Hopefully this will save someone some time. #Made2k's solution is fine, but does make your storyboard unnecessarily busy. If you don't need to use a UIViewController, then just do your work inside a regular UITableViewController and save yourself a headache.
If you want to use a UITableView in a UIViewController you have to make the ViewController a data source and a delegate of the TableView and then implement methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
In case of a static table, in the cellForRowAtIndexPath you'd return outlets of the static cells. For a detailed description check out this answer:
https://stackoverflow.com/a/19110821/3110536
I ended up thinking about this in a different kind of way. The problem I thought I was having was I wanted all the features that a navigation controller provides, but I needed this to be the base of the controller, i.e. nothing to go back to. I was thinking that the only way to do this was to create a UIViewController and add the table view and such in there, but what I came up with is to simply just create a new navigation controller and now this view shows up as the root view like so:
I don't know if this is the best practice, but hopefully it can help somebody else if they are having this problem.
Man, following Hack really works!
You should give it a try!
In my requirement I wanted to add buttons in my Static cells too!and Toggle the visibility of the TableView
[self.tableView setHidden:YES/NO];
and Reload it with new data
[self.tableView reloadData];
and so many things is possible with that way of doing it!
https://stackoverflow.com/a/19110821/1752988
Hope the above link would help you! (Y)
I have a static UITableView built from a Storyboard that works well. I want to fill the first category programmatically, though, from a user-defined file
Simply put, I want to go through all the strings in an array and add them as cells for the rows of the first category. For the second category, I have a series of mildly complex cells (containing a number of labels, textfields, buttons and other controls), defined in the storyboard, that I don't feel like recreating in code.
As far as I understand, the default behaviour for a UITableView built from a storyboard is to use the nib file as an implicit datasource. If I use a custom class as datasource, my second section doesn't work. I have thought of two possible ways to fix this:
Fill my first category from the datasource and delegate the rest to the nib file. Is this possible? Is there some method to programmatically ask the nib to fill my UITableView?
Export my storyboard-built cells into code and paste this code into my datasource. This method has the disadvantage of making my second category harder to modify.
Is one of those two options feasible? Is there another option?
I would use dynamic prototype cells. Then, I would set up the ViewController as the delegate and the dataSource. I would then create a custom subclass of UITableViewCell and connect the elements of the second section to IBOutlets in the custom UITableViewCell.
If the first section wasn't something that could be done with one of the generic cell types, I would also create a custom subclass of UITableViewCell for that section as well.
I would then use the cellForRowAtIndexPath: method to set up the cells with the information that I want in them. So if my first section used FirstSectionCell and my second section used SecondSectionCell as custom subclasses of UITableViewCell my cellForRowAtIndexPath: would look like this:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section==0)
{
FirstSectionCell *firstCell = [tableView dequeueReusableCellWithIdentifier:#"First Cell Prototype"];
//Set up the first cell.
return firstCell;
}
else if(indexPath.section ==1)
{
SecondSectionCell *secondCell = [tableView dequeueReusableCellWithIdentifier:#"Second Cell Ptototype"];
//Set up second cell.
secondCell.someLabel.text = #"whatever";
//etc.
return secondCell;
}
else
{
//if you have another section handle it here.
}
}
There are two kinds of table views when you use Storyboards:
Static
Dynamic
You're currently using the former. You define everything in the Storyboard and have very little code.
But you need to change to the latter.
You can still keep your UITableViewCells in the Storyboard; there's no need to do that in code (though you can if it makes things easier). You can refer to the template cells using the "reuse identifer."
Otherwise you've pretty much got it. You'll need to write code to implement the data source and (possibly) more methods of the table view delegate.
It's kind of fiddly switching from static to dynamic. I keep meaning to raise a Radar because I'm sure Xcode could be making it easier to do...
I have a UIView that will need to display two UITableViews, but they are never shown together, by using a SegementedBar you can toggle one or the other.
What would be the best way to handle this? Just create one Table View Controller and change the data source, or create 2 Table View Controllers and just hide one when the other is visible.
The 2 tables will have a completely different layout with different custom cells.
I would keep one datasource & delegate.
This means that all the delegate/datasource methods become more complicated BUT it means that you can retain the one to one relationship between viewController & view.
keep a reference to each of the table views
//vc.h
#property (nonatomic, weak) IBOutlet UITableView* firstTableView;
#property (nonatomic, weak) IBOutlet UITableView* secondTableView;
In the datasource/ delegate methods you need to account for the fact that the method needs to behave differently depending on which table view is in use. e.g.
//vc.m
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
if (tableView == self.firstTableView) {
...
} else { // tableView == self.secondTableView
...
}
}
return cell;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
if (tableView.tag == 1) {
...
} else { // tableView == self.secondTableView
...
}
}
tag could be assigned from the .xib.
so no need to have UITableVeiw variable in .h file.
Two table view in .xib needed
Both approach has some pros and cons, but i will personally prefer approach having two separate controller.
Approach 1 - create one Table View Controller and change the data source
This approach help in avoiding extra and repeated code.
With this memory management is good as using one controller only.(Although this is not a big concern till then we won't have a lot of data.)
Issue with this is having complexity.
Approach 2 - 2 Table View Controller
With this approach definitely have extra and repeated code.
But with this is less complexity.
In my current app, I need to have 4 UITableView in a single UIViewController, at once I've to show single table, based on the tab selected by the user, I've added four tables because, all of having different custom cells and functionality, to reduce complexity I took four.
The main benefit of this is that, each time you don't need to call reloadData to update a single table. I just need to properly handle table's show & hide flow. And believe me that's looks cool. Not flicking at all.
In my case, I am creating four tables by code only. And I make a method that will return me a table based upon a tag I've pass.
I keep cellForRowAtIndexPath as small as possible by dividing code into different functions.
Use separate UITableViewControllers and swap the views. It's less code, less complexity and it's the way Apple does it with the TabBar.
As for code complexity, there really isn't any. You simply do the following to switch views when the UISegmentedControl's value has changed:
UIView *previousSuperview = myViewController1.view.superview;
myViewController2.view.frame = myViewController1.view.frame;
[myViewController1.view removeFromSuperview];
[previousSuperview addSubview:myViewController2.view];
Alternatively, you could set the corresponding view's hidden property.
I'd like to know if someone there in the community has ever implemented 2 UItableView in on single view, I've searched a lot trough google but i'm not sure if I'm using the correct words. What I need is lo look like as the Facebook menu where shows 2 table views, here is an screenshot of my idea. Any ideas/tutorials/blogs you can provide me will be useful, Thanks a lot!
http://a1.mzstatic.com/us/r1000/119/Purple/eb/62/0a/mzl.uvhmahke.320x480-75.jpg
UITableView is simply a subclass of UIScrollView, which is a subclass of UIView, so, yes, you should be able to have more than one tableView in a single view. The only 'gotcha' with this is that your delegate and datasource callback methods for the table views need to either be broken out explicitly in each method (using if(tableView.tag == 0) or something) or either have completely different objects be the datasource and delegate callback methods. The tableviews don't care where they are located.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if(tableView.tag == 0){
//do something for first tableView
}
else{
//do something for other tableView
}
return cell;
}
The image you posted does not have two tableViews in a single view. It looks like there are two tableViews in two separate views, which would more than likely have completely different delegate and datasources.