I'm trying to use a UITableView without using a nib and without using a UITableViewController.
I have added a UITableView instance to a UIViewController Like So
mytable = [[UITableView alloc] initWithFrame:CGRectMake(22, 207, 270, 233)];
[mytable setDelegate:self];
[self.view mytable];
Also I have added the following table view methods to my UIViewController (cut for brevities sake)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
I am getting a warning saying that my UIViewController does not implement UITableView delegate protocol.
Whats the correct way to tell the table view where its delegate methods are?
(This is my first attempt at trying to use a UITableView without selecting the UITableTableview controller from the new file options)
You need to conform your class to the UITableViewDelegate and UITableViewDataSource protocols. ( cellForRowAtIndexPath: is in the UITableViewDataSource protocol )
Do this by using angle brackets in your class interface definition:
#interface myViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {...}
The reason why you are getting this warning now and not before when you were using a UITableViewController is because UITableViewController already conforms to these protocols.
So, in essence a UITableViewController is just a class that conforms to UITableViewDelegate and UITableViewDataSource, and has a UITableView instance member.
That's pretty much it.
Of course, if you're not already subclassing UITableViewController, then you need to manually setup the dataSource and delegate of the UITableView:
[tableView setDelegate:self];
[tableView setDataSource:self];
You also must set the dataSource delegate to self:
[tableView setDelegate:self];
[tableView setDataSource:self];
or, equally:
tableview.delegate = self;
tableview.dataSource = self;
The warning is just telling you that your #interface section should declare that you implement the UITableViewDelegate protocol:
#interface MyUIViewController : UIViewController < UITableViewDelegate >
[tableview setDataSource:self]
You have to give it definitely, Why because of the two required methods of UITableView are under UITableViewDataSource protocol.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
In Swift3 this is how you set UITableViewDelegate:
class FeedsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var feedsTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
feedsTableView.delegate = self
feedsTableView.dataSource = self
// Do any additional setup after loading the view.
}
}
Related
I am new in ios dev, so my question might be so easy!
I want to use a UITableViewController in different places (reusable), so as a .net developer I think to create one UITableViewController and load it in different views (like Partial views in MVC.net)
I know the UIView that wants to contain this table should implement UITableViewDelegate and UITableViewDataSource methods, but I don't want to do that, I mean I want the Partial view to handle all of those logics because that is the view that has the access to CoreData.
I already searched for different solutions and in almost all of them I have to implement those methods in every single view that wants to use that partial view.
any suggestion?
Thanks
Yes, you can handle the logic in the partial view for example your exTableviewController.
Handle protocol UITableViewDataSource & UITableViewDelegate in your exTableViewController as below.
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Test"];
if (cell==nil) {
cell= [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Test"];
// cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.textLabel.text = [NSString stringWithFormat:#"%i", indexPath.row];
return cell;
}
And associate the partial view and your view controller as below.
#interface YourViewController ()
#property (nonatomic, strong) exTableViewController *tableVC ;
#end
#implementation YourViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableVC = [[exTableViewController alloc] init];
[self.view addSubview:_tableVC.view];
// Do any additional setup after loading the view, typically from a nib.
}
#end
You can also customize the subview's size by using YourViewController.xib.
And binding self.tableVC with the subview in xib file.
Hope this can help you.
My goal is define my own cell style, with background, font and size. I try this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ScreenListElements *currentScreenElement = [self.screenDefBuild.elementsToTableView objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:currentScreenElement.objectName];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:currentScreenElement.objectName];
}
cell.textLabel.text = currentScreenElement.objectName;
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.contentView.backgroundColor = [UIColor blackColor];
}
I would like to change cell backgrond, but my app doesn't enter to willDisplayCell method. I have declared my class as:
#interface MyTableView : UIViewController <UITableViewDataSource,NSCopying> {
}
Should i have something else? Or maybe is a better way to declare own cell style.
#interface MyTableView : UIViewController <UITableViewDataSource, UITableViewDelegate ,NSCopying> {
}
the method
tableView:willDisplayCell:forRowAtIndexPath
is delegate method of UITableView
EDITED (to make it correct & accepted answer)
setting delegate
[myTableView setDelegate:self];
Ok, i saw, that you didn't implement the "UITableViewDelegate" protocol, only dataSource...
So it surely doesn't enter delegate methods.
Be sure it is like so:
#interface MyTableView : UIViewController <UITableViewDataSource, UITableViewDelegate ,NSCopying> {
}
Check UITableviewCell Delegate Protocol :
- (void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath{
cell.contentView.backgroundColor = [UIColor blackColor];
}
I had the same issue where I set all the things correct but if you have your function written manually you might miss the syntax and this error occurs:
(Instance method 'tableView(tableView:willDisplayCell:forRowAtIndexPath:) nearly
matches optional requirement tableView(_:willDisplay:forRowAt:) of
protocol UITableViewDelegate
This way the function is not going to be recognised, write the function correctly:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
If the delegate is assigned to self this will work, else it's gonna show the error as you write the code.
I know how to connect the datasource of a TableView in a Sotryboard, but not in a xib. I connect the datasource of my table with the viewController, and when I run it I get a SIGABRT. Is it enough? Do I have to write some code for the xib?
In .h file of your class adopt TableView protocols like this.
#interface EditProject : UIViewController<UITableViewDataSource, UITableViewDelegate>
When you connect datasource,delegate of UITableView at run time it will try to find these delegate and datasource methods if you have not written them then your application will crash.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//datasource method.
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//delegate method.
}
In .xib you do like this. Right Click on UITableView Controller and connect datasource and delegate to File's Owner.
Implement a class the follows the UITableViewDataSource Protocol, and provide the data via the protocol methods.
How can I access the UIView in which I have a UITableView, from the custom cells inside that table. I cant find a method to do that.
Thanks
You can add an instance variable that points to the UITableView and set it when creating/configuring the cell (e.g. in tableView:cellForRowAtIndexPath:). Make sure that your cell does not retain the tableView though.
Knowing your cell’s tableView, call [parentTableView superView] to access the UITableView’s parent view:
#interface PropertyListingCell : UITableViewCell {
__weak id parentTableView;
}
- (void) setParentTableView:(UITableView*)tv; // parentTableView = tv;
In UITableViewController implementation:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//dequeue/create and configure your custom cell here
[cell setParentTableView:tableView];
return cell;
}
UPDATE:
If you're using recent XCode (at least 4.3) you can simply add
#property (weak) UITableView *parentTableView; // use unsafe_unretained instead of weak if you're targeting iOS 4.x
to the #interface section of your UITableViewCell's subclass. Then, when you're creating a cell (in tableView:cellForRowAtIndexPath:) set this property accordingly:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// ...
//dequeue/create and configure your custom cell here
// ...
cell.parentTableView = tableView;
return cell;
}
And in your cell class call self.parentTableView to access the tableView this cell belongs to.
I just came across a situation where my implementation of a tableview is working in 3.2 but fails to fire any of the tableview methods in iOS 4. The view controller in question is defined as a UIViewController and is setup to adopt the UITableViewDataSource and UITableViewDelegate protocols, and I'm hooking the tableview up as the view's datasource and delegate via IB.
Definition in .h:
#interface FooViewController : UIViewController <UITableViewDataSource,
UITableViewDelegate> {
IBOutlet UITableView *itemTable;
}
#property (nonatomic, retain) IBOutlet UITableView *itemTable;
.m:
#synthesize itemTable;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(#"numberOfSectionsInTableView fired!");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
NSLog(#"numberOfRowsInSection fired!");
return 2;
}
- (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] autorelease];
}
return cell;
}
This appears to work fine in < 4.0, but in 4 it just simply bypasses firing any of these methods. Am I by chance doing it incorrectly and being caught up by something being fixed in 4.0?
Do you have the dataSource and delegate set for the itemTable? The rest of your code seems to look fine. Another question is why use the UiViewController instead of using the UITableViewController
I've been using the UITableViewController and it works quite well, and you can still just implement the simple basic methods you have implemented.