UISearchDisplayController—why does my search result view contain empty cells? - iphone

I am about to go out of my mind here, in my Core Data databse I have a lot of users, i have hooked the database up to a tableviewcontroller via NSFetchedResultController, and when the view loads, I see all my users, and i can perform a push to a detail viewcontroller via storyboard segue... so far so god, my tableview contains a custom cell with an image view and 2 uitextlabels that all has their tag values assigned..
Now, when I perform the search I create a new NSFetchedResultController with a predicate, and performs the performFetch.. I then get the fetchedObjects property and it contains the users that match, so the search request is also working like a charm.. in all my tableviews datasources I check if self.tableView == self.searchdispl.view to see which controller I should query data from.. In all the controllers delegates I check to see which controller is active so i know which view to reload. If i nslog a lot of data it is all fine behind the scenes, the delegate and datasource methods all use the correct view and fetchcontroller..
In my cellForRowAtIndexPath i can log out my user.name, and that is always correct, also when searching.
The issue is that the UISearchDisplayController view that is on top only has empty cells, unless i set my UITableViewControllers dynamic prototype cell to basic, then both tableviews contain that label with the users name ! The segue from the cell still doesn't work, but there is data in the cell.
It seems as the UISearchDisplayControllers view is a generic view, at least when it comes to segues and cell layout...
I have checked all the connections from the UISearchDisplayController to my UITableViewController, and all looks fine...
Why will the SearchDisplayControllers view not accept my cell layout and segue ?
Thank you :)
Update : has just figured out what is going wrong, but not found the solution yet.
In my cellForRowAtIndexPath the cell is always configured as the Default Cell when thr searchdisplayview is in this method.. Do i really need to create my cell in code for the uisearchdisplay to work ? Why can it not use the configured cell from the storyboard ?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"PersonCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSLog(#"Default Cell");
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSFetchedResultsController *controller = tableView == self.tableView ? self.fetchedResultsController : self.fetchedResultsControllerForSearch;
Person *p;
p = [controller objectAtIndexPath:indexPath];
[(UILabel*) [cell viewWithTag:1] setText:p.name];
[(UILabel*) [cell viewWithTag:2] setText:#"Status"];
if(p.avatarImage){
UIImage *avatar = [[UIImage alloc] initWithData:p.avatarImage];
[(UIImageView *) [cell viewWithTag:3] setImage:avatar];
}
return cell;
}

The issue was that when i got the cell in cellforrowatindexpath, it didn't get it from the original viewcontrollers tableview, so i changed the line from
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
to
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
and now all is good, the cell has the layout from storyboard and segues works like a charm..

Related

Where to use scrollToRowAtIndexPath in iphone?

I am using [self.messageList scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; in cellForRowAtIndexPath and it is working fine, when a row is added in table array then it auto scroll upside but the problem is that when I try to see the top rows then it automatically come again last rows. And I am not able to see my all rows. Please let me know where I use this or any other approach to do this.
cellForRowAtIndexPath method is not called for all cell that you have. It is only called for visible cell in your TableView. When You Scroll UITableView then it ask to UITableView that you want to use reusable cell or add to new one. generally we use reusable cell so, it is use 1st no of cell and add at end of cell . it is not create another new cell at the end. so, when you scroll your UITableView it not scroll to end of cell it indexPath is similar to indexPath of first no of cell. so you can not scroll your UITableView at to Down.
use following code may be helpful for you.... :)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
[self.tblView scrollToRowAtIndexPath:indexPath atScrollPosition: UITableViewScrollPositionTop animated: YES];
// your code
}
// your code
return cell;
}
If you write this code in your cell for row at index path, then it will get called every time you try to scroll manually coz this message is called to draw your cell and you will b directed to the row you specified. Try checking your indexpath in a IF--Else block and scroll only when a certain action happens.
cellForRowAtIndexPath is a method for creating a cell to view .When you scroll this method is called when a cell is viewed.So each time the method called the [self.messageList scrollToRowAtIndexPath:indexPath method(which is called inside cellForRow) is also called and the table scrolls down to that row!!!

Custom CellIdentifier is Null When Using Search Display Controller

In my tableview have custom cells that I initialize from a UITableViewCell class. I have sections for first letters of records and have an indexPath that is being created dynamically.
I wanted to add a search display controller to my tableview. So I did, created all methods to filter data. I am sure that my functions are working well because I am printing array count to screen for search results.
My problem is that the first time view loads, the data is on the screen. But when I hit the search input and type a letter, than I get 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:' error. After I used a breakpoint I saw that my custom cell is nil after searching. Data is exist, but cell is not being initialized.
Here is the code I use for custom cell initializing:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ObjectCell";
SpeakerCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *myObject = [[sections valueForKey:[[[sections allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.label1.text = [myObject objectForKey:#"myValue"];
return cell;
}
I believe I made a mistake when putting controls in IB. So I added screenshots of objects:
Connections inspector for my table view
Connections inspector for my search display controller
EDIT: Problem is actually solved, I have used a UISearchBar instead of Search Display Controller but I guess this issue remains unsolved. So I'm willing to try any ways to make it work.
As of here search display controller question,
you need to access the self.tableView instead of tableView:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"CellId"];
// do your thing
return cell;
}
For those using iOS 5 and StoryBoards, you would want to use the following method instead of initWithIdentifier:
initWithStyle:(UITableViewCellStyle)stylereuseIdentifier:(NSString *)reuseIdentifier
Example:
NSString *cellIdentifier = #"ListItemCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
I'm not sure about how this should work in storeboarding.
But normally you would check if the [tableView dequeueReusableCellWithIdentifier:CellIdentifier] returns a cell.
Because if the cell in not loaded before or there aren't any cells to reuse you will have to create a new cell:
SpeakerCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[SpeakerCell alloc] initWithIdentifier: CellIdentifier];
}
Also when in declaring local variables in Objective-C we tent not to capitalize the first letter.
I had the same issue, with custom cells (built in Storyboard) not being drawn as soon as the first letter was put in the search field. The search was successful however.
Finally I found a good tutorial from Brenna Blackwell suggesting to configure manually the cell drawing in the corresponding subclass of UITableViewCell, adding UILabels and other items.

uitableviewcontroller does not show anything

I have storyboard and implement master detail application app ,when i assign manuel class to a tableviewcontroller the objects inside it does not showed and i only get blank table ,please help.
“I defined it as Static Cells and then assign manual class ,I use default code when you add uitbleviewcontroller subclass ,i use the default codes and didn't change the code.”
Well of course it’s blank, you’re not giving the table view any data to work with. You need to implement cellForRowAtIndexPath and configure each cell there.
A sample implementation would be:
-(UITableViewCell *) tableView: (UITableView *) tableView
cellForRowAtIndexPath: (NSIndexPath *) indexPath {
UITableViewCell *cell = [self.table dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"CellIdentifier"];
}
cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row];
return cell;
}
You should read the table view programming guide.

iOS 5 Storyboard Custom Cell Crash: UITableView dataSource must return a cell

This is either an XCode bug, or me missing a crucial rule here.
Update:
- What's the chance of this being a weird bug in XCode/Storyboard?
Situation:
iOS 5, Storyboard
This is the storyboard setup: http://i.imgur.com/T5WyD.png
Another screenshot of the full setup: http://i.imgur.com/1tVuz.png
TableViewController with Custom Cell, cell has reusable identifier "NewCell"
in "cellForRowAtIndexPath" I basically have:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"NewCell"];
return cell;
This throws an exception:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
Things I have already tried:
I setup a new project from scratch, TabBarController, with a TableViewController and a Custom Cell, all wired up in Storyboard, set a reusable cell identifier. Used the same code as above, worked perfectly. I don't know why it didn't work with the storyboard above...
I have a feeling it has something to do with the tree I built there, which is a TabBarController, loading a NavigationController, loading a TableViewController, providing a few items, one is clicked, which loads another TableViewController, which is unable to work with the custom cell, somehow.
Important:
- The issue is that the Storyboard should make sure that:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"NewCell"]; will never return NIL (unlike without the Storyboard/iOS4). But, mine is nil. And I can't, for the hell of it, figure out what's happening.
Heyo, I just had this problem today and figured out a few possible causes. To link a UITableView as a subview of a ViewController in Story board check that you have done these steps.
In your "ViewController.h", add <UITableViewDataSource> to your list
of protocols
#interface ViewController : UIViewController
<UITableViewDataSource>
you might want to add <UITableViewDelegate> as well but I didn't.
In your "ViewController.m" set up your Table view data source
functions
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [yourCells count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NewCell *cell = (NewCell *)[tableView
dequeueReusableCellWithIdentifier:#"NewCell"];
if (cell == nil) {
NSLog(#"Cell is NIL");
cell = [[CustomCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
return cell;
}
In Storyboard, connect the UITableView's "Data Source" and
"Delegate" references to the ViewController.
In Storyboard, give the Prototype Cell the Identifier "NewCell"
If these are done, I believe it should work.
Hope this helps =)
I always use custom cells in the storyboard like this:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
return cell;
Make sure the number of rows/sections is at least one. And another thing to check is that you set the UITableViewController to your custom class name in the storyboard.
Did you double check the cell prototype identifier is "NewCell"?
Your setup as Tabbar->navigationcontroller->tableview is perfectly fine. I
am using this layout all the time.
verify also there's no useless runtime attributes anywhere in this
viewcontroller/tableview/cell.
your prototype looks a bit weird there - you added a UIButton to the cell as subview? why?
To solve this problem add the following just above your dequeueReusableCellWithIdentifier statement:
static NSString *CellIdentifier = #"NewCell";
making sure the identifier matches the prototype cell in Storyboard
It maybe late to answer this but i bet this will fix all your problems

Hierarchical UITableview

In my first view I have a UITableView with 5 records. In UITableView cells are holding two different components. One UILabel is text and another UILabel shows value for that cell.
On selection of this UITableViewCell user is navigated to another view where I have given a picker controller for changing the value of 2nd label in the table view for the selected row. I reload the UITableView data on -viewWillAppear but this overlaps the text on lables as many times I visit it.
Can anyone give me relevant example of hierarchical tableview where UItableViewCell's right section is dependant on selection of picker from next view.
I think you are adding the labels on cell.contentView everytime you reload the table, but are not removing the previous ones. Thats why the overlapping is happening.
try to remove the lables
- (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];
}
for (UIView * view in cell.contentView.subviews) {
[view removeFromSuperview];
view = nil;
}
// add your labels
}