I have a UITableView that loads from a NIB file. The controller for the screen is a subclass of UIViewController that conforms to the UITableView delegate protocols. This is the 2nd screen in a stack of views managed by a UINavigationController.
In my viewWillAppear for the offending view I run two NSFetchRequests and update 2 of the 3 sections in my table with results from those NSFetchRequests. At the bottom of viewWillAppear I call
[self.myTable reloadData];
myTable is an IBOutlet to the UITableView for the screen.
For whatever reason the table doesn't reload the data and none of the delegate methods for the table get called when I come back up to it from views deeper in the Navigation Controller hierarchy.
How do I get the table to reload?
Thanks.
Instead of self.tableView, use:
[myTable reloadData];
So if you defined your IBOulet as myTable, then you need to use that name instead.
self.myTable would work if you initialized myTable like in your header:
self.myTable = [[UITableView alloc] initWithFrame:CGRectZero];
Have you also linked the UITableView to data source and delegate outlets in the nib file? You have to link these two in addition to the IBOutlet.
Related
I have a controller named as "firstViewcontroller" where i have a UITableView named as "discoveredInstanceTableView". I want to load that UITableView in to another UIViewController named as "secondViewcontroller"
I have used the below code but it is not working, It says property "discoveredInstanceTableView" not found ...Anybody please help me:
In the firstViewcontroller:
IBOutlet UITableView *discoveredInstanceTableView;
In the Secondviewcontroller:
firstViewcontroller *vc1 = [[firstViewcontroller alloc]initWithNibName:#"firstViewcontroller" bundle:nil];
[self addChildViewController:vc1];
[self.myTableview addSubview:vc1.discoveredInstanceTableView];
What you asked is valid only if you curious to know why the above thing is not working answer would be
You are doing something that is not allowed, this can not be done as per the documentation.
However, If we forget about the right wrong approach, you probably adding a table view as a subview over a table view itself and I am sure you passing a table view to a table view which might not be allocated.
First think about the UITableView how it works? it simply a ScrollableView which display content over its cells.
Eventually would recommend you read about TableView
EDIT: From the Above Comments
IMPORTANT: You should not embed UIWebView or UITableView objects in
UIScrollView objects. If you do so, unexpected behavior can result
because touch events for the two objects can be mixed up and wrongly
handled.ยป As UITableView is a UIScrollView, this applies here as well.
Possible Alternatives of displaying TableView inside the SecondViewController
Use #Rajath Kornaya's Answer And In my opinion that is not right approach since whenever you required callback action like on cell tap, you want to display an alert(or something else), you can't get the delegate callback inside the SecondViewController
But there are so many other right approaches available, that you should follow up.
Create a TableView separately either programmatically or through the XIB/Storyboard
Add delegate and data source (methods which responds when something interesting happened e.g Cell going to populate called cellForRowAtIndexPath) to current SecondViewController
Define all required data source methods and write proper code.
If you required to do something on cell tap, add specific delegate method too.
But if you want to reuse the FirstViewController Class TableView simply create a CustomView and add TableView inside there and simply add that view to each view controller class.
I hope it may helps you!!!
declare in viewcontroller2
#property (nonatomic, strong) UITableView *table;
create table in viewcontroller1
tableView=[[UITableView alloc]initWithFrame:CGRectMake(10, 10, 250, 300) style:UITableViewStylePlain];
[self.view addSubview:tableView];
tableView.backgroundColor=[UIColor greenColor];
while calling viewcontroller2 pass table to viewcontroller2
ViewController2 *v2=[[ViewController2 alloc]init];
v2.table=tableView;
UINavigationController *navigation=[[UINavigationController alloc]initWithRootViewController:v2];
[self presentViewController:navigation animated:YES completion:nil];
in viewcontroller2 access the table using the global variable
[self.view addSubview:self.table];
I have a table view cell with a "Show More" button. On clicking the button I want the delegate
-tableView:didSelectRowAtIndexPath: to get called ?
Can someone tell me the difference between the following 2 statements:
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
and
[[self.tableView delegate] tableView:self.tableView didSelectRowAtIndexPath:indexPath];
There shouldn't be any difference between those two statements, assuming that self is the delegate of the table view, and you have a property called tableView in your controller that points to the table view (connected to the table view in IB if it's an outlet, or assigned to the table view in code if you created the table view there).
I couldn't find an example with good explanation how to include UITableView in my project using MVC pattern.
Let's say that at the beginning I have only two files 'MainViewController' (:UIViewController), and 'MainModel' (:NSObject) containing my Array with data for cells.
Where I should have a reference to UITableView object, which file should be delegate for table, ... ?
Your MainViewController will have a view property that you should point to your UITableView instance. You can have any object be your delegate, but usually your delegate is the view controller that controls it, which would be your MainViewController.
That said, there's a subclass of UIViewController called UITableViewController that you should probably be using as the superclass of MainViewController. It has some automatic functionality for controlling UITableViews. In fact, instantiating a UITableViewController (or any its subclasses) will automatically create a UITableView and point to it in its view & tableView properties.
So your MainModel is the model. MainViewController is your controller. The tableView is your view. Add it as a property to your MainViewController and set your MainViewController to be the dataSource and delegate for the tableView. Then when you are populating the tableView, use the data in your MainModel. For instance:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[MainModel sharedInstance] myArray].count;
}
Or create an NSArray property on MainViewController and populate it from MainModel in viewDidLoad or viewWillAppear.
When I work with a TableViewController I am able to setup all my content in storyboards. Since I use Static Cells instead of Dynamic Properties for my table view, I find this method much more convenient and easier to implement. I hook up the new UITableView class and simply delete all the delegate methods. Works like a charm as ALL of the content / buttons are being setup in storyboards.
I am trying to accomplish the same result, except this time, I have to work within a ViewController and add a TableView as a subview. Once I hook up the right class, add my outlet connection and setup the following delegates:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MainCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
This works well if my TableView is set to Dynamic Properties :
But when I change the Table View content to Static Cells and delete the delegate method, my app crashes. So, How can I add a table view with Static Cells (That I can manipulate in storyboards) to my ViewController?
Here is what you can do. In your storyboard, create a parent view controller that contains all your non tableview views also, create a UITableViewController. In your parent view controller, create container view, delete the view controller it auto adds, and right click and drag from the container view to your UITableViewController to create an embed segue. Your end result should look something like this:
As far as I know, you can't do this directly. At least in iOS 6, you had to use a UITableViewController when using static cells. One way to use a static table view inside a UIViewController would be to add a container view in IB, and make the embedded controller a table view controller (delete the UIViewController you get automatically, drag in a UITableViewController, and hook it up with the embed segue). You can get a reference to this table view controller from the UIViewController by implementing prepareForSegue:sender:, and using the destinationViewController property (which will point to the table view controller).
You still need to do a couple of things:
Add <UITableViewDataSource, UITableViewDelegate> to your #interface declaration.
Then you can set these also in Interface Builder.
Implement cellForRowAtIndexPath and call the dequeueReusableCellWithIdentifier method to return the cell.
Sorry, I was wrong. The truth is you cannot use static cells without a UITableViewController. Sorry.
A solution could be that you create two controllers and just add the view of the table view controller to your other view controller.
I would like to use my viewDidLoad function in my tableViewController.
How can I make viewDidLoad run in my controller?
tableViewController = [[TableViewController alloc] init];
UITableView *tableView = [[UITableView alloc] init];
tableViewController.view = tableView;
....
From Apple documentation:
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
So you can try to instantiate it from NIB or overwrite the loadView method. Another step from Apple documentation:
If you cannot define your views in a storyboard or a nib file, override the loadView method to manually instantiate a view hierarchy and assign it to the view property.
viewDidLoad will be called when the view is actually loaded, which will happen after you present your view controller, by, e.g.:
adding it to a navigation controller,
adding it to a tab bar controller,
presenting it modally.
This is the missing bit in your code. If you explain how you would like to present your view controller, I may help further. Also, have a look at this: Presenting View Controllers.
(I assume the fact that you tried to override the view property of your table view controller was just an attempt "to make things work" -- but you do not need to do anything about that, the view controller will be correctly set up with a table view inside of it).
tableViewController = [[TableViewController alloc] init];
tableViewController.tableView // This is your newly generated tableview
viewDidLoad will be called after you assign the tableView to another parentview