I have integrated a searchBar in my application. And it worked fine. But after adding new elements to my tableView my searchBar does not work anymore. I get error messages in this code block:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // Here i get: >Control reaches end of non void function<
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
if (searching)
{
VerwaltungInformation *searchedFormel = [copyListOfFormularies objectAtIndex:indexPath.row] ; //Here i get: >Thread 1: Program received signal "SIGABRT"<
cell.textLabel.text = searchedFormel.nameFormel;
}
else
{
NSDictionary *dictionaryCell = [listOfFormularies objectAtIndex:indexPath.section];
NSArray *arrayCell = [dictionaryCell objectForKey:#"Formel"];
VerwaltungInformation *cellValue = [arrayCell objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue.nameFormel;
}
return cell;
There seems to be a problem with the cellIdentifier - but I can not figure it out.
Thanks for any help!
The warning Control reaches end of non void function comes when you wrapped up your non void method without returning an object. To figure out your problem, right click your mouse select Structure select Re – Indent. Now you can find out the structure of your code more easily and find out what is happening.
I suspect the problem might be earlier in the source file, above the method you posted. Please try this:
Step 1:
#implementation MyClass
#synthesize ...
#if 0
// all of the code that precedes cellForRowAtIndexPath
#endif
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// and so on
Does the compiler still warn on the CellIdentifier? My guess is no (though you'll probably see all kinds of errors below, related to symbols that you hid inside #if #endif).
Step 2:
Move the #if #endif pair to wrap methods one at a time in the file, method by method, starting with the method above the one you posted, until the CellIdentifier warning reappears. When it does, you'll have found the source of the problem.
Related
I am overriding tableView:commitEditingStyle:forRowAtIndexPath to become a method that resets the textlabels in my uitableviewcells however this seams to be causing errors when the user next touches the uitableview.. it has to be touched once before itll do anything (so it takes two touches to actually get any response.)
Im hoping someone can help who has also been in a similar situation;. My code is below.. I have debuged it down to the tableView:commitEditingStyle:forRowAtIndexPath method as if I comment out tableview:titleForDeleteConfirmationButtonForRowAtIndexPath: method the same thing still happens.. So i think i am doing something wrong by overriding the other method.
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
return #"Clear";
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
//[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
//reset uitableviewcell textlabel with default input "empty"
vehicleSearchObjectString = #"empty";
[self.tableView reloadData]; //reloads the tabels so you can see the value.
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
UPDATE
This is where I set my uitableviewcell textlabel
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"VehicleSearchCell" owner:self options:nil];
cell = vehicleSearchCell;
self.vehicleSearchCell = nil;
}
// Configure the cell...
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if(indexPath.section == 0)
{
if(indexPath.row == 0)
{
UILabel *label1;
label1 = (UILabel *)[cell viewWithTag:1];
label1.text = #"Manufacture";
UILabel *label2;
label2 = (UILabel *)[cell viewWithTag:2];
label2.text = vehicleSearchObjectString;
}
//...
If you're in this method, you've enabled editing on the table, I suggesting checking where/when it is disabled, as this could be the cause for a click looking like ignored.
Another lead I would follow is to avoid the reloadData method which fires quite a lot of things and sometimes not controllable by the developer. You've got the indexPath so you can target the single cell for updating by using :
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
on the table view.
Last thing I would investigate is Apple's comment on updating tables :
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/ManageInsertDeleteRow/ManageInsertDeleteRow.html#//apple_ref/doc/uid/TP40007451-CH10-SW1
It says that the commit... method must call the method :
deleteRowsAtIndexPaths:withRowAnimation:
or similar for insert, but it doesn't what happens if not.
So I have solved the problem!... I basically deleted the views .h.m.xib started again pretty much copied my code right across to the file and it works perfectly... I have no idea why this happened maybe something I did when I very first set it up.. I'm not sure...
This seems like an obvious feature that should be there but i can't find it.
For example if my class is a uitableviewdelegate whats the quickest way for me to see all the available delegate methods and add the ones im interested in to my implementation file?
You can use the tip in the first link that Simon posted above to get the method signatures for a delegate. After that, adding the code is up to you.
What I like to do is to choose the delegate methods that I most often use, and add them to a code snippet.
For example, for UITableViewDatasource I have a snippet called "UITableView Datasource Required Methods" containing:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"myCellName";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease];
}
//customize cell before showing it
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return <#numRow#> ;
}
Then I drag that snippet into my code whenever I'm creating a table delegate.
So, I am posting my code below.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath // I get a warning here Incomplete method implementation //
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
NSLog (#"Dobby4");
NSInteger row = [indexPath row];
cell.text = [dogArray objectAtIndex:row];
//I get a warning for the line above-- 'text' is deprecated //
return cell;
}
So,
1. I get a warning - incomplete method implementation for that function.
2. I get another warning 'text' is deprecated'
3. I tried debugging and tried to print a line "Dobby4" - and it DID NOT print.
I would appreciate some help.
I doubt it is do with this function. Probably the method before. It would be good if you put that in the code listing too.
You shouldn't be using the text property to set the text (it is as the warning says, deprecated). Use the textLabel which is a subview of cell. So that line will be cell.textLabel.text = [dogArray objectAtIndex:row];.
Since it is not printing Dobby4, either your numberOfSectionsInTableView: or tableView:numberOfRowsInSection: is returning 0. If this is not so, then you haven't connected your datasource properly.
1) The compiler could be moaning as the method implementation may not be present in your header file or vice versa?
2) the .text property of a UITableViewCell is indeed deprecated since iOS 3.0 so you will not be able to use it, seeing as you are definitely targeting a higher iOS version.
3) Perhaps linked to 1).
Hope this was of some help, keep us posted!
- (NSInteger)numberOfSectionsInTableView:(UITableView *)cijferTableView{
return 1;
}
- (NSInteger)cijferTableView:(UITableView *)cijferTableView numberOfRowsInSection:(NSInteger)section {
return [marksArray count];
}
- (UITableViewCell *)cijferTableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [marksArray objectAtIndex:indexPath.row];
return cell;
}
I have a marksArray which is filled with strings.
The code worked fine until a quarter of an hour ago but since then it has been crashing when I load the view this code is in, without me changing anything.
When I, in interface builder, disconnect the datasource however, the view is loaded properly without a crash. But of course, it won't fill the table in that case.
What did I do wrong?
Update:
The error the console gives is terminate called after throwing an instance of 'NSException'
Also, i didnt exactly add anything into marksArray just yet. To test, i just have this:
//.h
NSMutableArray *marksArray;
and
//.m
marksArray = [NSMutableArray arrayWithObjects:#"1", #"2", nil;
It looks like you did a search and replace for "tableView" with cijferTableView and in doing so you renamed the methods, which will cause this to break. For example:
- (NSInteger)cijferTableView:(UITableView *)cijferTableView numberOfRowsInSection:(NSInteger)section {
return [marksArray count];
}
should be...
- (NSInteger)tableView:(UITableView *)cijferTableView numberOfRowsInSection:(NSInteger)section {
return [marksArray count];
}
1) You forgot to retain marksArray
2) Weird names for dataSource methods ('cijfer' stuff instead of tableView:numberOfRowsInSection: and tableView:cellForRowAtIndexPath:). They will not work.
Why are you renaming your delegate methods? Maybe those are causing some of your problems?
I have a UITableView with several datasources. This is because, I need to switch the data with a UISegmentedControl, and if I add them as subviews, I cannot use the statusBar to scroll up, etc.
At first, I show a login screen:
self.tableView.dataSource = loginTableView;
self.tableView.delegate = loginTableView;
[self.tableView reloadData];
Then, once the user has logged in, I do the following to change to index:1 of the segmentedControler, which is their profile:
self.tableView.dataSource = profileTableView;
self.tableView.delegate = profileTableView;
[self.tableView reloadData];
However, the table view updates, but is a bit of a mix between the two dataSources. Some of the text has changed, some is overlapping, while some of it is completely missing.
Is there another way I should be changing the dataSource for a UITableView?
Thx
I had the exact same problem. My solution was to make the tableView hidden, change it's source, reload the data and make the tableView visible again.
Example in C# (MonoTouch):
tableView.Hidden = true;
tableView.Source = newTableViewSource;
tableView.ReloadData();
tableView.Hidden = false;
Not sure why this is happening from the code you have posted.
Instead of changing the delegate and datasource, swap out whatever ivar represents the data being displayed:
- (NSArray*)tableData{
if(showingLogin)
return self.loginData;
return self.profileData;
}
Now you only have 1 UITableViewController instance, but a BOOL to tell you which datasource to use.
The table view is caching the cells internally it uses for displaying your data. So if you change the data source you should also check that your is - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method is updating all the cells to the correct new values.
From your description it sounds like it is using the cached UITableViewCell instances and is not updating it to the correct new data in all cases. Perhaps code like this:
- (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];
cell.frame = CGRectZero;
cell.textLabel.font = //Set font;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.text = #"My Text for this cell"; // <==== Not good! Move it out of this if block
}
// Set cell text here
}
The simplest solution I found for this sort of problem is to just make the String you use for the cell creation (CellIdentifier) depending of the data Source. In this case you don't mix the cell of the different content types (and this helps you also if the cells need to have a different look depending on the mode).
I had this problem, turned out it was because my CellIdentifiers were the same...
static NSString *CellIdentifier = #"Cell";
Change one of them and the cells layout properly
static NSString *CellIdentifier2 = #"Cell2";
Wow, that's freaky.
The last time I did something like this, I simply used multiple views, hiding one and showing another when the segmented control was tapped. There are other possible solutions, but this is probably easiest and perhaps most efficient.
I have the same issue and what you have to do is use a different cell identifier within - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath.
if (self.segmentedControl.selectedSegmentIndex == 0) {
self.cellIdentifier = #"segmentOne";
} else {
caseAtIndexPath = [self.awaitingReviewCaseList caseAtIndex:indexPath.row];
self.cellIdentifier = #"segmentTwo";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier forIndexPath:indexPath];