Why is my UISearchDisplayController accessing an illegal cell / indexPath? - ios

I have a table view with a search bar. Initially, the table view shows all (10) items. When I select a cell, a detail view is pushed on the navigation controller stack, and I can then go back to the table view by tapping the Back button. As long as I have not entered a search text yet, the table view shows all items, and I can go back and forth between the detail view and the table view indefinitely.
When I enter a text in the search bar, the table view is updated correctly with the self.searchDisplayController.searchResultsTableView (say it only shows 8 items now), that means
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
is called 8 times (section 0, rows 0 to 7). Fine.
I can then tap a cell, see the detail view, and go back to the table view showing the 8 items.
If I then select a cell in the table view still showing the 8 items (the same cell as before or a different one, does not matter), I again see the detail view, and then tap the "Back" button,
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
is called for section 0, row 8, which is not existing, since the searchResultsTableView still only shows the 8 items (rows 0 to 7) from the search.
I don't really understand what is going on:
the search works correctly,
but cellForRowAtIndexPath is called with a "wrong" indexPath
EDIT: Removed assumption about mixing up the two table views - everything seems to be in the correct place, but cellForRowAtIndexPath is still called for row 8. Also note that it's ALWAYS row 8.
EDIT 2: Here is the cellForRowAtIndexPath. "Zeichen" is a DAO, the getZeichenForIndexPath:indexPath returns the correct instance from the search result.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SearchResultCell" ];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SearchResultCell"];
}
Zeichen *zeichen = [self getZeichenForIndexPath:indexPath];
UIImage *img = [UIImage imageNamed:zeichen.filename];
cell.imageView.image = img;
cell.textLabel.text = [zeichen description];
return cell;
}

I think you should control tableView == self.searchDisplayController.searchResultsTableView. This control should be in didSelectRowAtIndexPath: method as well.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == self.searchDisplayController.searchResultsTableView)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SearchResultCell" ];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SearchResultCell"];
}
}
else
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" ];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
}
return cell;
}
other thought: [tableView dequeueReusableCellWithIdentifier:#"SearchResultCell" forIndexPath:indexPath] usage is more convenient, if you are initialize your table view in storyboard or nib (setting cell identifier in storyboard).

Related

UITableView - insert new row by tapping on existing cell

I use UITableView with prototype cells and would like the top most cell to be an "adder" cell: when user taps on that cell, the segue is being performed. As the UITableView is being dynamically generated (except the top one) and cells are being reused, I have two question:
1 - is it possible to make one static cell while all the others will remain prototype cells?
2 - If not, how to implement this solution? I think, it has to be implemented in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
but I have no idea, is this method right place to do it. Am I correct, to implement this custom cell, I need to check, whether indexPath.row = 0 and substitute the needed cell with custom, while programmatically shifting all the cells one row down?
Yiu can do on the Tap of Your cell, you can create two different cell, one your prototype cell and one for your details
in your
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
AdderCell *cell = (AdderCell*)[tableView dequeueReusableCellWithIdentifier:#"AdderCell" forIndexPath:indexPath];
} else {
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:#"CustomCell" forIndexPath:indexPath];
}
}
on tap of your Adder cell in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
// add data to your row array and reload the tableRow
} else {
// do your tap action
}
}

First cell always empty in table. Display only from the second cell - Objective c

I have a table view which display the contacts from array. I setup the table view delegates by follows.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [contactArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ContactCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [contactArray objectAtIndex:indexPath.row];
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60.0;
}
But the first cell in the table view always empty. It starts display only from second cell. I thought it may be header view. So I removed the header using the following delegate methods.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 0.0;
}
But still have the problem. I attached the screenshot about this issue.
Any help will be appreciated.
Your TableView is fine and it is working correctly, this is due to some other problem that is included in iOS 7, that automatically scroll insets. To solve this problem, go to your storyboard and select the viewcontroller in which your TableView is and select the ViewController and select the Properties of that ViewController, and uncheck this checkbox, which is read as Adjust ScrollView Insets. See this screen shot,
Your table is correct.Just your table was auto adjusted by the viewController.
You can write self.automaticallyAdjustsScrollViewInsets = NO;
Your Deduction is wrong your first cell isn't missing, but your tableview has started by 64 points down. So change your frame of your tableview or your tableview constraints accordingly.
Tip : Try setting a background colour when you have to debug things like this to clear your doubts.

How to add extra cell in cellForRowAtIndexPath?

For example, I have 3 articles and when I display articles I want to display one more cell before the first one (that would be then 4 total).
I need to display that first article which is not in array and then articles which are in array.
UPDATE
I have tried next:
- (NSInteger)tableView:(
UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return ([arr count] + 1);
}
But my app then crash sometimes and I see over NSLOG then that app enters cellForRowAtIndexPath before I call [tableView reloadData].
This is something you should not really do.
Well, you can cheat the framework by returning a view (from -tableView:cellForRowAtIndexPath:) which would contain 2 subviews: your "first article" cell and the original first cell; don't forget to modify -tableView:heightForCellAtIndexPath: as well (otherwise your view would get cut).
But in general, you should change you data model behind the table view to dispay 4 cells – this is just a more valid approach.
You can do like this :
Return an additional row using this method :
// Each row array object contains the members for that section
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [YouArray count]+1;
}
At the end check for this added row :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Create a cell if one is not already available
UITableViewCell *cell = [self.mContactsTable dequeueReusableCellWithIdentifier:#"any-cell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"any-cell"] autorelease];
}
//Identify the added row
if(indexpath.row==0)
{
NSLog(#"This is first row");
}
else{
// Write your existing code
}
}
You need to add a extra value in the array using insertObject
[arr insertObject:[NSNull null] atIndex:0];
And implement the methods like:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arr count];
}
- (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];
}
if([arr onjectAtIndex:indexPath.row] == [NSNull null])
{
// 1st cell extra cell do your stuff
}
return cell;
}
Do you keep all your articles in an array? You should add the new article to the array too. The array is your datasource. I take it that you'd want to insert the new article as the first element in your array if you'd like it to appear in the top cell. As soon as you've updated your array you should call [mytableView reloadData] which triggers all the datasource methods to be called and reload your table's data.

Questions with Prototype Cell and UITableView

I have two kind of cell, one a standard title-subtitle cell, and another custom cell with two UITextField. And they have different identifier, VIEW and EDIT.
In my code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
I need to create two kind of cell. At any time, I have only one cell in edit, so I create a NSUInteger to keep track of which cell is being edited.
My code looks like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell;
if ( rowInEdit == indexPath.row )
{
cell = [tableView dequeueReusableCellWithIdentifier:#"EDIT"];
if ( !cell )
{
cell = [[UITableViewCell alloc]init];
}
RLSite* site = [[RLSettings settings]siteAtIndex:indexPath.row];
[[cell textLabel]setText:site.name];
[[cell detailTextLabel]setText:site.url];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:#"VIEW"];
if ( !cell )
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"VIEW"];
}
RLSite* site = [[RLSettings settings]siteAtIndex:indexPath.row];
[[cell textLabel]setText:site.name];
[[cell detailTextLabel]setText:site.url];
}
return cell;
}
Notice that my first part is definitely flawed. I don't know how to create a cell with prototype, and how to assign reuseIdentifier to it. Furthermore, I don't know how to access those UITextField in that cell once it's created.
Can anyone help me?
e. how to create a cell with prototype you can follow these tutorials as I also learned it from one of these tutorials
Tutorials
First one Which I referred.
Second one
And to excess the added text views you need to assign them tag values (obviously distinct).
Then use the below code to excess them in side your tableView:cellForRowAtIndexPath: method.
UITextField *txtField = (UITextField *)[cell viewWithTag:8];
Here replace the 8 with your tag value :)

Cannot access the Custom UILabel in a Custom UITableViewCell

this is Nsr (just a beginner in xcoding), using xcode 4.3.3,
I've made a Custom UITableview with Custom UITableviewcell through storyboarding,
I have a UIBUtton and a UILabel in my custom cell.
i'v remove the cell selection (also cleared the background) so that only the buttons can be accessable which works as a backgound for the custom UILabel.
Now there are bunch of buttons since of using data array, and when i click any button, it segues to the other view (detail view), all i wanted is to set the custom Label (set over the detail view) from the previous selected button with "Label"...
means new Label = previous page's clicked Label from the custom tableview..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
Custom *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[Custom alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.myLabel.text = [myArray objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self.myTable reloadData];
}
I hope you get my problem, very sorry for my poor english..
Please help me, im in a real mess, coz this problem already took my 3 days :(
Thanx in advance, Cheers.
function return Custom cell but in header you write UItableviewCell change this to Custom

Resources