I have a array which stores all the contacts from the phone. I have a UITableView in which i want to display all the contacts. I was having trouble displaying them in the table view o i created a new array, and used the below code to loop through the contacts array and fetch strings from it and store them in the new array (contactsNew)
for (CNContact *contact in contacts)
{
NSString *string = [formatter stringFromContact:contact];
[contactsNew addObject:string];
NSLog(#"contact = %#", string);
}
The issue is all the contacts are displayed in the log, but i am still not able to display the contacts in table view.
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [contactsNew count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [contactsNew objectAtIndex:indexPath.row];
return cell;
}
I have checked the values of 'string' variable and the number and content being added to the contactsNew array, and everything looks fine.
Also can i use something else in place of:
cell.textLabel.text = [contactsNew objectAtIndex:indexPath.row];
So that i can directly use the contacts array instead of creating a new array. Thanks in advance.
You need to reload tableView after creating array so use [tableView reloadData] after for loop
for (CNContact *contact in contacts)
{
NSString *string = [formatter stringFromContact:contact];
[contactsNew addObject:string];
NSLog(#"contact = %#", string);
}
[tableview reloadData]; //Add this line
Hope this will works.
you need to reload tableview after some delay.
use like this
for (CNContact *contact in contacts)
{
NSString *string = [formatter stringFromContact:contact];
[contactsNew addObject:string];
NSLog(#"contact = %#", string);
}
// add after Delay 0.5 if its not worked then 1.0
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[tableview reloadData];
});
Try this
for (CNContact *contact in contacts)
{
NSString *string = [formatter stringFromContact:contact];
[contactsNew addObject:string];
NSLog(#"contact = %#", string);
}
[tableview reloadData];
you have to reload your table on main thread after you fetch the contacts... like:- dispatch_async(dispatch_get_main_queue(), ^{ [_table reloadData]; });
...and for your table view write
cell.textLabel.text = [contactsNew objectAtIndex:indexPath.row]valueForKey:#"keys";
...provide the key here.
Here are few points you need to check to resolve your issue :
First thing you need to check is weather tableview methods called once after you added values to new Array ? If no than try reload table view after you are adding values to new array.
If it calls correctly after adding values to new array try to NSLog values in cellForRowAtIndexPath method
Hope it will help you.
Related
I have an array of dictionaries where I what to implement search functionality and display data on tableView cells.
Search works quite fine, I have tested it:
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSString *dictionryKey = #"eViela";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K CONTAINS [cd] %#", dictionryKey, searchText];
NSArray *filteredArray = [self.allItems filteredArrayUsingPredicate:predicate];
NSLog(#"%#", filteredArray);
self.sortedText = filteredArray;
[self.tableView reloadData];
}
Now I need tableView to fill data only for key "eViela" while user is typing info in search bar. As of now I can show only all items as per below code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SearchCell" forIndexPath:indexPath];
EvielasLibrary *library = [[EvielasLibrary alloc] init];
cell.textLabel.text = [[library.library objectAtIndex:indexPath.row]
return cell;
}
I know that it should be easy but I can't figure it out.
Thanks for help!
You need to get Model from array instead of create new one .
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SearchCell" forIndexPath:indexPath];
EvielasLibrary *library = [self.sortedText objectAtIndex:indexPath.row]; // assume that self.sortedText is your data source array of tableview
cell.textLabel.text = #"" // populate your string here
return cell;
}
NSMutableArray *arrayForTableView = [[NSMutableArray alloc] init];
NSString *dictionryKey = #"eViela";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",dictionryKey];
NSArray *filteredArray = [self.allItems filteredArrayUsingPredicate:predicate];
for (NSInteger i = 0; i<filteredArray.count; i++){
NSString *matchValue = [NSString stringWithFormat:#"%#",[filteredArray objectAtIndex:i]];
if ([matchValue isEqualToString:dictionryKey]){
[arrayForTableView addObject:matchValue];
}
}
Use arrayForTableView array for your tableview
cell.textLabel.text = [arrayForTableView objectAtIndex:indexPath.row];
Problem is that you not updating numberOfRowsInSection delegate method for sortedArray
You need to check if search bar is active or not. if search bar is active then use sortedText array else if search bar is not active then use library.library array
For check search bar active create a global variable isSearchBarActive And assign it true value in searchBarTextDidBeginEditing delegate function and assign false in searchBarTextDidEndEditing
Add Condition in numberOfRowInSection
if searchBarActive {
return self.sortedText.count
}
else {
return library.library.count
}
Add Condition in cellForRowAtIndexPath like this
if searchBarActive {
cell.textLabel.text = [self.sortedText objectAtIndex:indexPath.row]
}
else {
cell.textLabel.text = [library.library objectAtIndex:indexPath.row]
}
I'm trying to populate my tableView with storaged data in CoreData. When tableView is trying to populate it's cells the name and also date of fields in cell are empty. Size of NSMutableArray created from NSArray like so:
-(void)copyArrayToTableMutableArray:(NSArray *)coreDataArray
{
if(self.fetchedRecordsArray != nil)
{
modelArray = [NSMutableArray arrayWithArray:coreDataArray];
NSLog(#"%d", [modelArray count]);
}
}
shows that there are for example 3 items. When program goes to populate section it creates cell but they are empty. This is code for populating:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
CustomTableCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if([modelArray count] > 0)
{
Kwejki *tmpModel = [modelArray objectAtIndex:indexPath.row];
//Here it is empty NULL
NSLog(#"%#",[tmpModel name]);
cell.titleOfCell.text = [tmpModel name];
cell.dateOfAddedCell.text = [[tmpModel date] stringValue];
}
return cell;
}
And I'm saving new item to the CoreData like this:
-(void)addNewPosition:(ScrollViewViewController *)ScrollController recentlyDownloadedItem:(KwejkModel *)modelTmp
{
NSLog(#"DODAJE NOWA POZYCJE");
NSLog(#"%#",[modelTmp description]);
NSLog(#"%d", [modelArray count]);
//[self.tableView reloadData];
Kwejki * newEntry = [NSEntityDescription insertNewObjectForEntityForName:#"Kwejki" inManagedObjectContext:self.managedObjectContext];
NSLog(#"%#", [modelTmp getNameOfItem]);
newEntry.name = [[NSString alloc] initWithString:[modelTmp getNameOfItem]];
newEntry.rating = [modelTmp getRateOfPosition];
newEntry.urlMain = [modelTmp getUrlAdress];
newEntry.contentUrl = [modelTmp getContentUrl];
newEntry.coverUrl = [modelTmp getCoverImage];
newEntry.date = [modelTmp getDateOfItem];
NSError *error;
if (![self.managedObjectContext save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
else{
NSLog(#"UDALO SIE!!!");
}
[modelArray insertObject:newEntry atIndex:0];
[self.tableView reloadData];
}
I've searched around but haven't founded why it is empty. Do you know why?
For Core Data populated table views you should be using a NSFetchedResultsController. Then you can retrieve your object reliably with
Kwejki *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
The following is not recommended:
If you really want to stick to your ill-advised array solution, it would help to make sure you have a property or instance variable. Clearly, in cellForRowAtIndexPath your array has already been deallocated.
#property (nonatomic, strong) NSMutableArray *modelArray;
It doesn't look like you are using UIManagedDocuments so you may need to put a [self.managedObjectContext save] in add new position after you populate your newentry fields. I know you shouldn't have to do this that the data is there in memory, but if you are using different contexts in your insert and in your fetches, you wouldn't see the data until a save was done on it. It may not help, but give it a try.
I'm trying to build a function that will check if a retrieved JSON value have changed (messagecount in a given conversation). I'm populating a TableView with my JSON data and I would like to store the value in a dictionary and compare them later when I do a data update.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ConversationsModel* conversation = _feed.conversations[indexPath.row];
static NSString *identifier = #"ConversationCell";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:identifier];
}
[self getMessageCountToDictionary:conversation.messagecount id:conversation.conversationid];
cell.textLabel.text = conversation.title;
return cell;
}
And my method to store the values in a NSMutableDictionary:
- (void)getMessageCountToDictionary:(NSNumber*)messagecount id:(NSString *)conversationid
{
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
if (conversationid != NULL) {
[dictionary setValue:conversationid forKey:[NSString stringWithFormat:#"%#", conversationid]];
[dictionary setValue:messagecount forKey:#"messageCount"];
dictionaryCopy = [dictionary mutableCopy];
}
NSLog(#"Stored in dictionary %lu", (unsigned long)dictionary.count);
}
NSLog returns 2
Well, I'm not sure if I'm on the right track here for what I intend to do. All inputs are highly appreciated.
I would recommend to use key-value observer to watch your objects changing values.
You can read more about it here:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html
I have an array of EventObject(s). Each object has title and city and many others attributes. I want to show title of cell as event title, and subtitle of cell as event city. I tried doing that in the following, but I only get the last object displayed 4 times (that is the number of objects in the array).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
// NSDate *object = _objects[indexPath.row];
// cell.textLabel.text = [object description];
EventObject *eventInstance = [[EventObject alloc] init];
int row = [indexPath row];
eventInstance = eventObjectsArray[row];
cell.textLabel.text = eventInstance.eventTitle;
NSLog(#"Event Title: %#", eventInstance.eventTitle);
cell.detailTextLabel.text = eventInstance.eventCity;
return cell;
}
What did I do wrong? I am learning objective-c so beginners errors surely. Thanks
EDIT: This is how I am inserting objects:
//get events from database
eventsDictionary = [eventInstance getEventsObjects];
//process each key in dictionary and assign to eventInstance
for(id key in eventsDictionary)
{
eventInstance.eventId = [NSString stringWithFormat:#"%#", key[#"id"]];
eventInstance.eventTitle = [NSString stringWithFormat:#"%#", key[#"title"]];
eventInstance.eventDescription = [NSString stringWithFormat:#"%#", key[#"description"]];
eventInstance.eventCity = [NSString stringWithFormat:#"%#", key[#"city"]];
[eventObjectsArray addObject:eventInstance];
}
Suggestions
[This can be issue]
While adding objects in your eventObjectsArray make sure to have new insatnce of EventObject everytime before you add object
EventObject *eventInstance = [[EventObject alloc] init];
eventInstance.eventTitle = #"your title";
eventInstance.eventCity = #"your city";
[eventObjectsArray addObject:eventInstance];
[This is suggestion as you should know this to improve your coding standard and memory management]
While retriving objects back from array you really don't need to have instance of custom object rather have refrence to it like
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
//EventObject *eventInstance = [[EventObject alloc] init]; //you don't need this
int row = [indexPath row];
EventObject *eventInstance = eventObjectsArray[row]; // make reference like this
cell.textLabel.text = eventInstance.eventTitle;
NSLog(#"Event Title: %#", eventInstance.eventTitle);
cell.detailTextLabel.text = eventInstance.eventCity;
return cell;
}
I'm programming a simple in-house economics app for our company, but I'm facing some problems. I populate a UITableView with information from dynamically generated objects 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:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
Payments *project = [appDelegate.projects objectAtIndex:indexPath.row];
if([project.parentProject isEqualToString:bottomTabBar.selectedItem.title]) {
NSLog(#"%# är lika med %# index: %d",project.parentProject, bottomTabBar.selectedItem.title, indexPath.row);
// Configure the cell...
NSMutableString *changeInValue = [[NSMutableString alloc] initWithFormat:#"%d",[[project.amountsek objectAtIndex:0] intValue]-[[project.amountsek objectAtIndex:1] intValue]];
if([changeInValue intValue] >= 0) {
[changeInValue insertString:#"+" atIndex:0];
cell.imageView.image = [UIImage imageNamed:#"up.png"];
} else {
cell.imageView.image = [UIImage imageNamed:#"down.png"];
}
NSMutableString *foreignCurrency = [[NSMutableString alloc] initWithString:#""];
if(![project.currency isEqualToString:#"SEK"]) {
[foreignCurrency appendFormat:#" - %#%d",project.currency,[[project.payments objectAtIndex:0] intValue]];
}
NSString *detailString = [[NSString alloc] initWithFormat:#"%#%d (%#)%#",#"SEK",[[project.amountsek objectAtIndex:0] intValue],changeInValue, foreignCurrency];
[changeInValue release];
[foreignCurrency release];
cell.textLabel.text = project.name;
cell.detailTextLabel.text = detailString;
[detailString release];
}
project = nil;
return cell;}
And everything works like a charm! However! When I press another tabButton I want it to reload the table and to display only the matched elements! (The matching works fine, the log prints out everything correctly) Although, the old table cells does not empty before the new ones are added.
Here's the code for the reload tabItem:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
NSLog(#"Tab clicked: %d", item.tag);
[sourcesTable reloadData];
}
How do I solve this?
I'm new to programming for the iPhone and I could really use some help.
Please call [sourcesTable reloadData]; in viewWillAppear method of that ViewController.m
This call every time when your view is appears.