UITableView didSelectRowAtIndexPath method not firing - objective-c

I placed a TableView on my xib file with the following method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"FIRED THE EVENT");
}
and it doesn't seem to be firing when I click on a cell in the table. Is there something that I'm missing?

Be sure to include UITableViewDataSource, UITableViewDelegate in your .h file

Related

Error adding UITableView to ViewController on storyboard

On my storyboard I have a ViewController and I want to add a UITableView with 1 section and 2 static cells. That's all I'm doing right now but I get this error when compiling.
Static table views are only valid when embedded in UITableViewController instances
What am I missing?
Look at This question. Basically the same thing.
Any further questions, just ask! :)
Edited stuff:
UITableViewController *controller = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
[self.view addSubview:controller.tableView];
Then all you need to do is adding the UITableViewDataSource in the header file and you need the datasource methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if([indexPath row] = 0){
do something
}else if([indexPath row] = 1){
do something else
}
I think you just have to set datasource and delegate methods of the tableView in your .h file
#interface viewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
and then link it to your tableView in storyboard.
Please notify if it works..

Failing to properly declare/implement UITableViewDataSource methods

I have a UIViewController that I want to use to implement the methods of UITableViewDataSource on. I have this header, FriendsController.h:
#import <UIKit/UIKit.h>
#interface FriendsController : UIViewController <UITableViewDataSource>
#end
Edit: now updated the #interface declaration to:
#interface FriendsController : UIViewController <UITableViewDataSource, UITableViewDelegate>
and this implementation, FriendsController.m:
#import "FriendsController.h"
#implementation FriendsController
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(#"CALLED .numberOfRowsInSection()");
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"CALLED cellForRowAtIndexPath()");
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"FriendCell"];
cell.textLabel.text = #"Testing label";
return cell;
}
#end
When run this gives me a '-[UIView tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x81734d0'. Can anyone see if there is something wrong with my implementation/declaration of .numberOfRowsInSection()?
Edit: I've added a technique for method listing from here and run the view 'unconnected', it outputs the following list:
[<timestamp etc>] Method no #0: tableView:numberOfRowsInSection:
[<timestamp etc>] Method no #1: tableView:cellForRowAtIndexPath:
[<timestamp etc>] Method no #2: numberOfSectionsInTableView:
[<timestamp etc>] Method no #3: tableView:didSelectRowAtIndexPath:
[<timestamp etc>] Method no #4: viewDidLoad
Post scriptum: Both #ThisDarkTao and #Pei got it right, as can be seen in my previous question documenting the visual parts, here.
You need to add UITableViewDelegate to the list of protocols in the interface file, like this: <UITableViewDataSource, UITableViewDelegate>
You also need all of the following delegate methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1; // Number of rows
}
- (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];
}
cell.textLabel.text = #"Test Cell";
return cell;
}
In your xib/storyboard view, you also need to connect the tableview's delegate and datasource connections to the viewcontroller.
If you want your cells to 'do something' when you tap them, you also need to implement the following delegate method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Tapped cell %d",indexPath.row);
}
If you use the Storyboard in your project, you have to set the UIViewController's Class field to be your "FriendsController" on Identity Inspector of your storyboard.
So you can present your UIVIewController to be using your correct class (In this case, FriendController for you).
Pei.

Displaying different content view in the same uiviewcontroller by uitableview indexpath row

I want to show different UIImageView in the same UIViewController depends on which indexpath row was selected in UITableView. I have an unwise approach which was created lots of UIViewController for different UIImageView, But i don't want do this. Is there any smarter approach can fulfilled that. You help is very appreciated.
First add an UIImageView to the UIViewController's view.
Create a NSMutableArray to store UIImageViews, and in - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
imageView = [imageViewArray objectAtIndex:indexPath.row];
}

"Cannot find protocol declaration for ..." in adopting class objective c

I'm a little frustrated at the moment with the custom delegate process in objective-c. I've used the design pattern a few times already and have a pretty good understanding of how it works. I've searched the internet for 2 hours trying to find what I'm doing wrong in this instance, and to no prevail. I also compared my past use of custom delegates that are functioning properly vs. this instance and can't see any conceptual difference. so here we go:
I'm making a custom dual table view (one table for the list, and the other to hold the selections made from that list.) so that the user can make basic selections. here is the header file:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#protocol ListSelectorViewDelegate
-(void) listTableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
-(void) selectTableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
-(void) listTableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;
-(void) selectTableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;
- (void)listTableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)selectTableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
#end
#protocol ListSelectorDataSource
-(UITableViewCell *)listTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
-(UITableViewCell *)selectTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
-(NSArray *)sectionIndexTitlesForListTableView:(UITableView *)tableView editStatus:(BOOL) status;
-(NSArray *)sectionIndexTitlesForSelectTableView:(UITableView *)tableView editStatus:(BOOL) status;
-(NSInteger)listTableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index;
-(NSInteger)selectTableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index;
#end
#interface ListSelectorViewController : UIViewController {
//Delegate
id <ListSelectorViewDelegate> listsDelegate;
id <ListSelectorDataSource> listsDataSource;
//Titles
IBOutlet UINavigationBar *pageNavBar;
IBOutlet UINavigationBar *selectNavBar;
IBOutlet UINavigationBar *listNavBar;
//Tables
IBOutlet UITableView *selectTable;
IBOutlet UITableView *listTable;
//Table Data
NSMutableArray *listItems;
NSMutableArray *selectItems;
//Search Bars
IBOutlet UISearchBar *selectedSearch;
IBOutlet UISearchBar *listSearch;
BOOL listTableIsSearching;
BOOL selectTableIsSearching;
}
#property(nonatomic,assign) id <ListSelectorViewDelegate> listsDelegate;
#property(nonatomic,assign) id <ListSelectorDataSource> listsDataSource;
-(IBAction) newItem:(id)sender;
-(IBAction) selectAll:(id)sender;
-(IBAction) clearSelections:(id)sender;
#end
Notice the formal protocol declarations. Also note that this, along with the .m file compile fine. When I try to write a class to adopt the protocol I get the error "Cannot find protocol declaration for "ListSelectorDataSoure" ". I get the same message for the "ListSelectorViewDelegate" as well. Here is the .h file for the delegate class:
#import <Foundation/Foundation.h>
#import"ListSelectorViewController.h"
#interface ListSelectorDelegateTemplate : NSObject
<ListSelectorDataSource,ListSelectorViewDelegate>{
}
#end
Note that I am importing the ListSelectorViewController.h where the protocol declarations are found. Also note that when typing " " it does auto complete which means it does see it. Like I said, I've done it this exact way for other objects with no issues and cannot wrap my head around this one ... Any Help at all would be greatly appreciated
Ok figured it out.... extremely stupid answer here...
I originally created the ListSelectorViewController in a separate project and added it to the current project I'm working on... for some reason the .h and .m were not visible to the rest of the project and was the reason for the errors. simply added a new file to the project and copied over the contents of the original class.
Got this problem today too. It is a xcode bug indeed.
my delegate protocol file was modified by git merge confliction, I fixed the confliction, but all my files using this delegate still cannot find this delegate protocol file.
so i delete these two files by reference ,and add them to project again. it worked!
If ListSelectorViewController.h also imports ListSelectorDelegateTemplate.h, you'll get errors like that. You should move any imports that you can into the ".m" file, and replace them with #class declarations if necessary.
Got the same problem today. This seems to be a xcode bug.
Anyway my solution was to create an empty h. file, declare my protocol there, and then #import this new h. file anywhere where i was using it.
You have put my protocol declaration on separate file and import it then
what worked for me was cleaning the project (shift+command+K) simple.
In my case the error was caused by a cyclic #import. The delegate protocol declaration file included the implementor of the delegate . The implementor included the delegate protocol declaration file.

UITableView with multiple datasource

I have a ViewController that needs to use 2 UITableViews.
1 is always showing, while the other will show up as a popup after you click on a button on the view.
Typically I set the delegate and datasource to the File's Owner. However, since 1 of the UITableViews is in a popup, I'm not sure how to best tackle this.
e.g how do I tackle this part -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
Please advice.
You should have instance variables for both table views declared in your controller:
#interface MyViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
UITableView *mainTableView;
UITableView *popupTableView;
}
In each data source or delegate method, you can check which table view is being passed by the caller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == mainTableView)
{
// Code to create and return a main table view cell
}
else if(tableView == popupTableView)
{
// Code to create and return a popup table view cell
}
}