problem with the if statement - objective-c

i m parsing a json file.the logic goes like this, if there is no data in the variable named boy.it got to enter the if loop and if there is data it got to enter the else part.but the problem is even if the variable boy is empty(which shows empty in the console) the loop still enters the else part..cud u guys help me out..below is the code..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
NSDictionary *boy=[url objectAtIndex:indexPath.row];
NSLog(#"the boy value:%#",boy);
if (boy == NULL)
{
Secondetailview *detailViewController1 = [[Secondetailview alloc] initWithItem:boy];
[self.navigationController pushViewController:detailViewController1 animated:YES];
[detailViewController1 release];
}else
{
FirstViewDetail *detailViewController = [[FirstViewDetail alloc] initWithItem:boy];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
}

I would try to use if (boy == nil) but that doesn't seem to work either.
Instead do this:
NSString *str = [NSString stringWithFormat:#"%#", boy];
if ([str isEqualToString:#""]) {
//boy is nil do your stuff
}

Replace
if (boy == NULL)
with
if ([boy count] == 0)

Modify your if condition as below and see if that works.
((boy == NULL) || ([boy count] == 0))

Related

TableViewController , SearchBar and TableViewCell

When I searching and after filtered select in displays row that opens only the first letter DetailView (for example A letter).Others letters don't open. NSLog and breakpoint not helping. I don't understand what is the problem.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *keyTitle = cell.textLabel.text;
NSDictionary *peopleUnderLetter = [self.propertyList objectForKey:self.letters[indexPath.section]];
__block NSDictionary *selectedPerson = nil;
[peopleUnderLetter enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
if ([key isEqualToString:keyTitle]) {
selectedPerson = obj;
*stop = YES;
}
}];
if (selectedPerson) {
DetailViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
// Push the view controller.
[self.navigationController pushViewController:vc animated:YES];
[vc setDictionaryGeter:selectedPerson];
}
}
#pragma mark Search Display Delegate Methods
-(void)searchDisplayController:(UISearchController *)controller didLoadSearchResultsTableView:(UITableView *)tableView {
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
}
-(BOOL)searchDisplayController:(UISearchController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[filteredNames removeAllObjects];
if (searchString.length > 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains [search] %#", self.searchBar.text];
for (NSString *letter in letters) {
NSArray *matches = [[self.propertyList[letter] allKeys]filteredArrayUsingPredicate:predicate];
[filteredNames addObjectsFromArray:matches];
}
}
return YES;
}
after selecting every cell must open the detailviewcontroller with their data.Search bar shows every letter after filtered.But when I click cell doesn't open detail view (except first cell) .
Hard to tell without seeing the whole file but it looks like your problem may be this line. You are pulling the object out of self.propertyList using the section not the row. Which makes sense as to why it works only on the first row, which would have a row of 0 and an section of 0
`NSDictionary *peopleUnderLetter = [self.propertyList objectForKey:self.letters[indexPath.section]];`
Try changing it to :
`NSDictionary *peopleUnderLetter = [self.propertyList objectForKey:self.letters[indexPath.row]];`

Segue doesn't work because of searchbar

I have made a table where depending on which cell you click on you will be sent into a new scene (detailviewcontroller). For example if you click on the cell with the text Thailand you will be sent to ThailandDetailViewController (scene). Everything works until you use the searchbar (look under - (void)tableView).
-When some countries get outfiltered (because of the searchfunction) the reaming countries will go higher in the table and acquire a lower count. Which leads to that they will lead to the wrong detailviewcontroller (scene).
A friend of mine said to me that I should use objectAtIndex within my array, didnt really catch what he meant with that.. And make a switch on the cell.textLabel.text (didnt really follow him)
Here is my .m file:
- (void)viewDidLoad
{
[super viewDidLoad];
self.mySearchBar.delegate = self;
self.myTableView.delegate = self;
self.myTableView.dataSource = self;
totalStrings = [[NSMutableArray alloc] initWithObjects:#"America",#"Austria",#"Canada",#"France",#"Germany",#"Greece",#"Malaysia",#"Mexico",#"Netherlands",#"Poland",#"Russia",#"Singapore",#"Thailand",#"Ukraine", nil];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.row) {
case 0: [self performSegueWithIdentifier:#"Segue0" sender:self];
break;
case 1: [self performSegueWithIdentifier:#"Segue1" sender:self];
break;
//and so on
default: break;
}
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if(searchText.length == 0){
isFiltered = NO;
}
else
{
isFiltered = YES;
filteredStrings = [[NSMutableArray alloc]init];
for (NSString *str in totalStrings){
NSRange stringRange = [str rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location !=NSNotFound) {
[filteredStrings addObject:str];
}
}
}
[self.myTableView reloadData];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Cellidentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Cellidentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Cellidentifier];
}
if (!isFiltered) {
cell.textLabel.text = [totalStrings objectAtIndex:indexPath.row];
}
else //if it's filtered
{
cell.textLabel.text = [filteredStrings objectAtIndex:indexPath.row];
}
return cell;
}
Big thank you in beforehand!!
Well, you can have a custom class to store the area and the segue index like this:
#interface SegueVO : NSObject
#property (nonatomic, strong) NSString *area;
#property int segueIndex;
-(id)initWithArea:(NSString *)area andSegueIndex:(int)index;
#end
#implementation SegueVO
-(id)initWithArea:(NSString *)area andSegueIndex:(int)index
{
self = [super init];
if (self)
{
self.area = area;
self.segueIndex = index;
}
return self;
}
#end
You will then store your ares in the totalStrings array like this:
[[NSMutableArray alloc] initWithObjects:[[SegueVO alloc] initWithArea:#"America" andIndex:0],....
Of course you can create a factory method to cut down on initialisation code.
Now you can work out what segue to activate like this:
NSArray *arrayToUse = totalStrings;
if (isFiltered)
arrayToUse = filteredStrings;
[self performSegueWithIdentifier:[#"Segue"
stringByAppendingString:[NSString stringWithFormat:#"%i",
[arrayToUse[indexPath.row].segueIndex]] sender:self];
Hope this helps.
You could easily solve this problem by storing a custom object in your table's data model instead of an NSString. That object would contain the label to display plus the name of the segue to activate once selected.
It's another question why you'd want a totally different view controller for different data. I suppose these are different kinds of data that need different ways to deal with them.

get the title of a tableview titleForHeaderInSection

I have 4 sectioned tables in my iOS 6 app. These tables each have a title that I set in the titleForHeaderInSection. I would like to know how I can access this title with NSLog in didSelectRowAtIndexPath. I DO see the string value of the row I clicked on in the alert but I would also like the title of the tableview section. I'm not sure how to get that.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSMutableArray *sectionArray = [self.arrayOfSections objectAtIndex:indexPath.section];
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = selectedCell.textLabel.text;
NSLog(#"Selected Cell: %#", cellText);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Selected a row" message:[sectionArray objectAtIndex:indexPath.row] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
NSString *result = nil;
if ([tableView isEqual:self.myTableView] && section == 0) {
myTableView.tableHeaderView.tag = FROZEN;
result = #"Frozen";
} else if ([tableView isEqual:self.myTableView] && section == 1) {
myTableView.tableHeaderView.tag = FRUIT;
result = #"Fruit";
}
else if ([tableView isEqual:self.myTableView] && section == 2) {
myTableView.tableHeaderView.tag = SALADS;
result = #"Salads";
} else if ([tableView isEqual:self.myTableView] && section == 3) {
myTableView.tableHeaderView.tag = VEGETABLES;
result = #"Vegetables";
}
return result;
}
Store the titles of sections in an array as,
NSArray *sectionTitles = [NSArray arrayWithObjects:#"Frozen", #"Fruit", #"Salads", #"Vegetables", nil];
And modify your titleForHeaderInSection method as,
- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *result = [sectionTitles objectAtIndex:section];
//....
return result;
}
Modify didSelectRowAtIndexPath as,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//...
NSLog(#"Header title: %#", [sectionTitles objectAtIndex:indexPath.section]);
//...
}
Another option is to use the below method in didSelectRowAtIndexPath
NSLog(#"Header title: %#", [self tableView:tableView titleForHeaderInSection:indexPath.section]);
Well, it does seem like UITableView should provide access to this for you, but I'm not finding anything... The easiest way to implement this would be, I think, to create an array (I'll call it mySectionTitles and assume it's a property) with your section titles and then, in didSelectRowAtIndexPath, call [self.mySectionTitles objectAtIndex:indexPath.section] and do whatever you want with the returned string.

id transmission issue

This seems to be a very simple thing, but I don't know how to do it.
At moment I have rootView with the continents populated:
The code:
- (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];
}
// Configure the cell.
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
//Continent is the class. continents is an array to store data
Continent *cont=[self.continents objectAtIndex:[indexPath row]];
cell.textLabel.text=cont.continentName;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Continent *cont=[self.continents objectAtIndex:[indexPath row]];
SelectedContinent* selectedContinent=[[SelectedContinent alloc] initWithNibName: #"SelectedContinent" bundle: nil];
//NSLog(#"%#",cont.continentName);
[self.navigationController pushViewController: selectedContinent animated: YES];
[selectedContinent setTitle:cont.continentName];
[selectedContinent setContinentID:cont.continentID];
[selectedContinent release];
}
I created a new viewcontroller with nib file. Gave him tableView. And now I need to populate the countries from SQLite file. I made a DBAccess class which supposed to do all db manipulations and for every continent was written special method. Then it came to my mind that writing many methods is the stupid idea and the universal method came to world:
-(NSMutableArray*)getTheCountriesEurope:(int)continentID
{
NSMutableArray* euCountriesArray=[[[NSMutableArray alloc]init]autorelease];
NSString* sqlContinents = [NSString stringWithFormat:
#"SELECT countries.countryID,countries.countryName\
FROM countries\
WHERE countries.relativeToContinentID=%i"
,continentID];
/*const char* sqlContinents="SELECT countries.countryID,countries.countryName\
FROM countries\
WHERE countries.relativeToContinentID=?";*/
sqlite3_stmt *statement;
int sqlResult = sqlite3_prepare_v2(database, sqlContinents, -1, &statement, NULL);
if ( sqlResult== SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
Country *countryObj = [[Country alloc] init];
char *countryName = (char *)sqlite3_column_text(statement, 1);
countryObj.countryID = sqlite3_column_int(statement, 0);
countryObj.countryName = (countryName) ? [NSString stringWithUTF8String:countryName] : #"";
[euCountriesArray addObject:countryObj];
NSLog(#"%#",countryObj.countryName);
[countryObj release];
}
sqlite3_finalize(statement);
}
else
{
NSLog(#"Problem with the database:");
NSLog(#"%d",sqlResult);
}
return euCountriesArray;
}
anyway, this method also has issues and I was told to implement int sqlite3_bind_int(sqlite3_stmt*, int, int); method as well.
Well, at moment my problem is that I can't to catch the continentID value from RootViewController class I need it to feed to method this value as the parameter.
Have I done right when assigned countryID this way?
[selectedContinent setTitle:cont.continentName];
[selectedContinent setContinentID:cont.continentID];
in the RootViewController. If yes, then how to obtain that's variable's value?
At moment when I push another view I see only Title (At least it shows right)
SOS
You need to assign the values before you push the view.
[selectedContinent setTitle:cont.continentName];
[selectedContinent setContinentID:cont.continentID];
[self.navigationController pushViewController: selectedContinent animated: YES];

UINavigationController shows blank view

I am making a simple navigation based application that drills down one level and show a new xib file each time. When I drill down one level my screen shows up blank. I still have the navigation controller at the top with a back button but my view dosent load.
Here is my code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
circle_area *subViewOneController = [[circle_area alloc] init];
UIViewController *tvc = subViewOneController;
if (indexPath.row == 0 && indexPath.section == 0) {
[[self navigationController] pushViewController:tvc animated:YES];
}
}
like I said this returns a blank screen.
My updated Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
circle_area *subViewOneController = [[circle_area alloc] init];
UIViewController *tvc = subViewOneController;
switch (indexPath.section) {
case 0:
switch (indexPath.row) {
case 0:
NSLog(#"section %i special button!", indexPath.section);
NSLog(#"row %i special button!", indexPath.row);
break;
default:
break;
}
break;
default:
break;
}
NSLog(#"section %i!", indexPath.section);
NSLog(#"row %i!", indexPath.row);
NSLog(tvc.view.recursiveDescription);
if (indexPath.row == 0 && indexPath.section == 0) {
[[self navigationController] pushViewController:subViewOneController animated:YES];
}
[tvc release];
}
Last time i left out the switches in the middle, it dosent look like they would effect anything , but i included them this time.
circle_area *subViewOneController = [[circle_area alloc] init];
In this line, you are creating an instance of the circle_area class and assigning it to the pointer called subViewOneController.
UIViewController *tvc = subViewOneController;
In this line, you are assigning that same instance to a pointer called tvc. This pointer is defined to point to an instance of the UIViewController class.
It's not clear what you are trying to do here. What is circle_area? Why the redundant assignment? Is circle_area a subclass of UIViewController? If it isn't, then that's the problem and you should have been warned about it by the compiler.
In addition, you have a memory leak. You allocate memory for this circle_area instance, but you don't release it.