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];
Related
When I searching and then select row that opens only the first letter (for example A.Others letters don't open. NSLog and breakpoint not helping. I don't understand what is the problem.
#synthesize propertyList, letters, filteredNames, searchController , arrayPlace;
- (void)viewDidLoad {
[super viewDidLoad];
............
filteredNames = [[NSMutableArray alloc]init];
searchController = [[UISearchController alloc]init];
self.searchController.searchResultsUpdater = self;
NSString *path = [[NSBundle mainBundle] pathForResource:#"names" ofType:#"plist"];
self.propertyList = [NSDictionary dictionaryWithContentsOfFile:path];
self.letters = [[self.propertyList allKeys] sortedArrayUsingSelector:#selector(compare:)];
}
#pragma mark - Table view data source
.......
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"cell bg1.png"]];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
if (tableView.tag == 1){
NSString *letter = self.letters[indexPath.section];;
NSArray *keyValues = [[self.propertyList[letter] allKeys] sortedArrayUsingSelector:#selector(compare:)];
cell.textLabel.text = keyValues[indexPath.row];
} else{
cell.textLabel.text = filteredNames[indexPath.row];
}
return cell;
}
- (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];
}
}
And :
#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;
}
Search bar fails and he does select row after searching
If you want more information just say it to me by answers and I will edit my question and then you will edit your answer
Please explain again clearly. You search using any alphabet, it shows the result which has only "A". Is this what you're trying to say ? If so, then remove the above code and try the below approach :-
Drag a search bar into the view controller and set its delegate to self (You'll find its property in the storyboard's delegate property
to the view controller).
Add UISearchBarDelegate in the .h file that will take care of automatically calling the appropriate methods of the search bar of
which the delegate is set to self.
Use the below method to detect the search. You can filter the NSArray here and reload the table.
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
}
I'd recommend you to go through some basic tutorials about iOS development before getting deeper. All the best and I hope it helps you...
Screenshot
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.
After all progress i made with your answers, my issue changed. So i am changing my question with clearer way. I have an UITableView which is showing my retrieved data from Parse.com. So i made a NSMutableArray for adding objects to that array when they are retrieved. But my problem is even i add objects to NSMutableArray, my table does not show anything but default screen of UITableView. I thing the issue is UITableView is formed before my NSMutableArray got its objects. Here is my code:
Note: The PropertyClass is the class which has the properties of my objects.
At MyTableViewController.h
#interface MyTableViewController : UITableViewController <CLLocationManagerDelegate> {
PFObject *object;
}
#property (strong, nonatomic) IBOutlet UITableView *MyTableView;
#end
At UITableViewController.m
#interface MyTableViewController ()
#property(strong)NSMutableArray *myNSMutableArray;
#end
#implementation MyTableViewController
#synthesize myNSMutableArray,MyTableView;
-(void) retrievingDataFromParse{
PFQuery *query = [PFQuery queryWithClassName:#"MyObjectsClass"];
[query whereKey:#"ObjectsNumber" lessThanOrEqualTo:10];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(#"Successfully retrieved %d scores.", objects.count);
if (objects.count==0) {
NSString *objectError = #"There no object retrieved from Parse";
PropertiesClass *PC = [[PropertiesClass alloc]initWithPropert1:objectError Propert2:nil Propert3:nil Propert4:nil];
[myNSMutableArray addObject:PC];
}
for (int i = 0; i < objects.count; i++) {
object = [objects objectAtIndex:i];
NSString *Propert1 = [object objectForKey:#"Propert1"];
NSNumber *Propert2 = [object objectForKey:#"Propert2"];
NSNumber *Propert3 = [object objectForKey:#"Propert3"];
NSString *Propert4 = [object objectForKey:#"Propert4"];
PropertiesClass *PC = [[PropertiesClass alloc]initWithPropert1:Propert1 Propert2:Propert2 Propert3:Propert3 Propert4:Propert4];
[myNSMutableArray addObject:PC];
};
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.myNSMutableArray = [NSMutableArray array];
[self retrievingDataFromParse];
[MyTableView reloadData];
}
- (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 [myNSMutableArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PropertiesClass *PC= [myNSMutableArray objectAtIndex:indexPath.row];
cell.textLabel.text=PC.Propert1;
return cell;
}
Looking at your code i see that you never create a UITableViewCell, you should change this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PropertyClass *PC = [myMutableArray objectAtIndex:indexPath.row];
cell.textLabel.text = PC.x;
return cell;
}
with this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (nil == cell){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
PropertyClass *PC = [myMutableArray objectAtIndex:indexPath.row];
cell.textLabel.text = PC.x;
return cell;
}
the method dequeueReusableCellWithIdentifier:forIndexPath: return a UITableViewCell only if there are unused, but already allocated, cells in your table view. otherwise it returns nil.
Also when you update the mutable array containing all your data you should call [yourTableView reloadData] to force the table view to reload its content.
Your code is quite cryptic. Few suggestions here.
First, rename variables and methods with camelCaseNotation (camel case notation). For example, MyMutableArray should be myMutableArray. RetrievingDataFromParse should be retrievingDataFromParse (and so on). Start upper case letter are for classes.
Second, what does this code mean (I put comment on your code)?
for (int i = 0; i < objects.count; i++) {
// where do you have defined object?
object = [objects objectAtIndex:i];
NSString *x = [object objectForKey:#"x"];
NSNumber *y = [object objectForKey:#"y"];
NSNumber *z = [object objectForKey:#"z"];
NSString *t = [object objectForKey:#"t"];
// is Mekan a subclass of PropertiyClass or what else?
PropertiyClass *Properties = [[Mekan alloc]initWithx:x y:y z:z t:t]
// what's MekanKalibi? Maybe you need to add Properties
[MyMutableArray addObject:MekanKalibi];
}
Edit
If you don't use iOS6 - (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier you should alloc-init cells.
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(!cell) {
// alloc-init a new cell here...
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// or if you don't use ARC
// cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
PropertyClass *PC = [myMutableArray objectAtIndex:indexPath.row];
cell.textLabel.text = PC.x;
return cell;
Edit 2
I don't know how parse works but I suppose it manages async requests. So, at the end of your for loop, just call reload data in the table.
Parse states:
The InBackground methods are asynchronous, so any code after this will run immediately. Any code that depends on the query result should be moved inside the completion block above.
I had the same problem. When you reload the table, you need to move it so it is inside the block. Worked for me.
I'm not 100% sure how the asynchronous parts affect it so. I know that the start of my viewDidload and the end occured then this block, hence the problem.
People should probably up this as this solves the issue.
Cheers.
All you have to do is reload tableView in the block... this will show data.
for (int i = 0; i < objects.count; i++) {
object = [objects objectAtIndex:i];
NSString *Propert1 = [object objectForKey:#"Propert1"];
NSNumber *Propert2 = [object objectForKey:#"Propert2"];
NSNumber *Propert3 = [object objectForKey:#"Propert3"];
NSString *Propert4 = [object objectForKey:#"Propert4"];
PropertiesClass *PC = [[PropertiesClass alloc]initWithPropert1:Propert1 Propert2:Propert2 Propert3:Propert3 Propert4:Propert4];
[myNSMutableArray addObject:PC];
};
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
**[MyTableView reloadData];**
}];
My application's main window shows a SplitViewController. On the left is a TableView that displays the names. On the right is a DetailsView consisting of 2 textviews that displays the name and age.
This is the SQLite database and 'USERS' table i have created for my application.
-(NSString *)dataFilePath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"Mydata.sqlite"];
}
- (void)viewDidLoad
{
[super viewDidLoad];
if(sqlite3_open([[self dataFilePath] UTF8String], &database) != SQLITE_OK)
{
sqlite3_close(database);
NSAssert(0, #"Failed to open database.");
}
char *err;
NSString *sql = #"CREATE TABLE IF NOT EXISTS USERS" "(ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, AGE INTEGER);";
if(sqlite3_exec(database, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK)
{
sqlite3_close(database);
NSAssert(0, #"Failed to create table.");
}
}
I want to populate the TableView with the names. When a name is selected in the table, the textviews on the right side of the SplitViewController will display the selected name as well as the age.
May i know how to do this?
There are a number of questions in there. From the sounds of it you want to know how to load the values, how to display them in a tableview, how to send a message from the tableView to the mainview and then how to display the content in your main view.
First off create a model object for the 'User' object. Then in the user class write a static method that you can call that returns all the users in an array.
Once you have the array, use it to populate the tableView using the standard 'cellForRowAtIndexPath' method. Once the user taps on a cell, pass the selected user object over to the main view via a delegate method and then finally display its various details (name, age, etc) in your relevant labels that you will have in there.
If any of that is unclear let me know and I can post a code snippet to help you out.
EDIT: So.. code snippet for creating an object and loading it into the tableViewController (only writing the .ms):
For the User class
#implementation User
#synthesize pk, name, age;
#pragma mark - Public Instance Methods
+ (NSArray *)getAllUsers
{
sqlite3 *db = **However you get your db conn**
sqlite3_stmt *statement = nil;
NSMutableArray *userArray = [NSMutableArray array];
NSString *fullQuery = #"SELECT * FROM User";
const char *sql = [fullQuery UTF8String];
if(sqlite3_prepare_v2(db, sql, -1, &statement, NULL)!=SQLITE_OK)
NSAssert1(0, #"Error preparing statement '%s'", sqlite3_errmsg(db));
else
{
while(sqlite3_step(statement) == SQLITE_ROW)
{
User *currentUser = [[User alloc] init];
[User setPk:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 0)]];
[User setName:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 1)]];
[User setAge:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 2)]];
[userArray currentUser];
[currentUser release];
}
}
sqlite3_finalize(statement);
sqlite3_close(db);
return [NSArray arrayWithArray:userArray];
}
Now for your table View Controller:
- (void)init
{
self = [self init];
if (self)
{
[self setUserArray:[User getAllUsers]];
}
}
- (void)dealloc
{
[super dealloc];
[userArray release];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [userArray 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] autorelease];
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
}
User *currentUser = [userArray objectAtIndex:indexPath.row];
[[cell textLabel] setText:user.name];
return cell;
}
Hopefully that gives you an idea of how to proceed. If you are confused about how to proceed I recommend that you read up on the 'Model View Controller' Programming methodology and how table views work. Its a bit of work to start off with but you'll get there.
Hope that helps :)
I am making a little program that will put some events in a calendar on the iPhone. In the settings I will let the user select wich calendar to use. To present what calendars he can use I pull all calendars from the EKEventStore and sort out those that doesn't allow modifications. Those are subscribed from other websites.
After the filter, wich seems to be OK, the array is reduced from 5 to 3 calendars, all objects in the array are out of scope, and the list in the tableview is blank.
What am I missing?
Edit: The problem erupted when I started with the filtering, thats why I thought that was the problem, but now it seems that the objects go out of scope when the -(NSArray*)availableCalendar returns the array. Do I need to copy it or something?
Image here: http://d.pr/35HY
-(NSArray*)availableCalendars{
NSArray *calendars;
EKEventStore *eventDB = [[[EKEventStore alloc]init]autorelease];
calendars = [[[NSArray alloc]initWithArray:[eventDB calendars]]autorelease];
return calendars;
}
- (void)viewDidLoad {
[super viewDidLoad];
allcalendars = [self availableCalendars];
[allcalendars retain];
localCalendars = [[NSMutableArray alloc]initWithArray:allcalendars];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"allowsContentModifications == YES"];
[localCalendars filterUsingPredicate:predicate];
calendarCountInt = localCalendars.count; //When I break the code here, the three objects are 'Out of Scope' and the count is three
}
- (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];
}
if (calendarCountInt > 0)
{
cell.textLabel.text = [[localCalendars objectAtIndex:indexPath.row] title] ;
}
else {
cell.textLabel.text = #"No Calendars found";
}
return cell;
}
- (void)dealloc {
[localCalendars release];
[allcalendars release];
[super dealloc];
}
Your code is ... interesting. I'm guessing that you're doing return calendarCountInt; in your tableView:numberOfRowsInSection: method. If you are, then that's going to return 0; when there are no calendars that allow modification, resulting in an empty table.
Here's how I would do it:
// this requires an #property(nonatomic, retain) NSArray *allCalendars
// with a corresponding NSArray *allCalendars ivar
// also, an #property(nonatomic, retain) NSArray *localCalendars
// with a corresponding NSArray *localCalendars ivar
// get all calendars and cache them in an ivar (if necessary)
- (NSArray *)allCalendars {
if (allCalendars == nil) {
EKEventStore *eventDB = [[[EKEventStore alloc] init] autorelease];
[self setAllCalendars:[eventDB calendars]];
}
return allCalendars;
}
// get all modifiable calendars and cache them in an ivar (if necessary)
- (NSArray *)localCalendars {
if (localCalendars == nil) {
NSPredicate *filter = [NSPredicate predicateWithFormat:#"allowsContentModifications == YES"];
[self setLocalCalendars:[[self allCalendars] filteredArrayUsingPredicate:filter]];
}
return localCalendars;
}
// there's only one section
- (NSUInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
return 1;
}
// show the number of modifiable calendars, or 1 (if there are no modifiable calendars)
- (NSUInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSUInteger)section {
NSArray *local = [self localCalendars];
return ([local count] > 0) ? [local count] : 1;
}
// set up the cell
- (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];
}
if ([[self localCalendars] count] > 0) {
cell.textLabel.text = [[[self localCalendars] objectAtIndex:[indexPath row]] title];
} else {
cell.textLabel.text = #"No calendars found";
}
}
- (void)dealloc {
[localCalendars release], localCalendars = nil;
[allCalendars release], allCalendars = nil;
[super dealloc];
}