Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

PlutoM4

macrumors newbie
Original poster
Apr 11, 2014
10
0
Hi all! I'm struggling trying to populate a TableView and a DetailView from a plist.

My app's structure is:

Curiosita.h
Code:
@interface Curiosita : NSObject

@property (nonatomic, strong) NSString *titolo; // titolo della curiosità
@property (nonatomic, strong) NSString *testo; // testo della curiosità

@end

RecipeTableViewController.h
Code:
@interface RecipeTableViewController : UITableViewController <UISearchBarDelegate, UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UIBarButtonItem *sidebarButton;

@property (strong,nonatomic) NSMutableArray *filteredTipsArray;
@property IBOutlet UISearchBar *curiositaSearchBar;

RecipeTableViewController.m
Code:
@interface RecipeTableViewController () <UITableViewDataSource, UITableViewDelegate>
@end

@implementation RecipeTableViewController

{
    NSArray *titoloArray;
    NSArray *testoArray;
    NSArray *curiosita;
    NSArray *searchResults;
}

@synthesize curiositaSearchBar;
@synthesize filteredTipsArray;

- (void)viewDidLoad
{
    [super viewDidLoad];

// Find out the path of recipes.plist
    NSString *path = [[NSBundle mainBundle] pathForResource:@"curiositaPlist" ofType:@"plist"];
    
    // Load the file content and read the data into arrays
    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
    titoloArray = [dict objectForKey:@"Titolo"];
    testoArray = [dict objectForKey:@"Testo"];

   //Initialize the recipes array
    Curiosita *curiosita1 = [Curiosita new];
    curiosita1.titolo = [titoloArray objectAtIndex:0];
    curiosita1.testo = [testoArray objectAtIndex:0];
    
    Curiosita *curiosita2 = [Curiosita new];
    curiosita2.titolo = [titoloArray objectAtIndex:1];
    curiosita2.testo = [testoArray objectAtIndex:1];

curiosita = [NSArray arrayWithObjects: curiosita1, curiosita2, nil];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return [searchResults count];
        
    } else {
        return [curiosita count];
       
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 71;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CustomTableCell";
    RecipeTableCell *cell = (RecipeTableCell *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; //aggiunto forIndexPath:indexPath per popolare la table view dal plist
    
        
    // Configure the cell...
    if (cell == nil)
    {

        cell = [[RecipeTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    
    // Display recipe in the table cell
    Curiosita *recipe = nil;
    if (tableView == self.searchDisplayController.searchResultsTableView)
    {
        recipe = [searchResults objectAtIndex:indexPath.row];
    } else {
        recipe = [curiosita objectAtIndex:indexPath.row];
    }
    
    cell.titoloLabel.text = recipe.titolo;
    cell.testoLabel.text = recipe.testo;
    
    return cell;
} 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showRecipeDetail"]) {
        NSIndexPath *indexPath = nil;
        Curiosita *recipe = nil;
        
        if (self.searchDisplayController.active) {
            indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
            recipe = [searchResults objectAtIndex:indexPath.row];
        } else {
            indexPath = [self.tableView indexPathForSelectedRow];
            recipe = [curiosita objectAtIndex:indexPath.row];
        }
        
        RecipeDetailViewController *destViewController = segue.destinationViewController;
        destViewController.curiosita = recipe;
    }
}

-(IBAction)goToSearch:(id)sender {
    // If you're worried that your users might not catch on to the fact that a search bar is available if they scroll to reveal it, a search icon will help them
    // If you don't hide your search bar in your app, don’t include this, as it would be redundant
    [self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
    [curiositaSearchBar becomeFirstResponder];
}

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"testo contains[c] %@", searchText];
    searchResults = [curiosita filteredArrayUsingPredicate:resultPredicate];
}

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    [self filterContentForSearchText:searchString
                               scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                      objectAtIndex:[self.searchDisplayController.searchBar
                                                     selectedScopeButtonIndex]]];
    
    return YES;
}


@end

RecipeDetailViewController.h
Code:
@property (weak, nonatomic) IBOutlet UITextView *titoloDetail;
@property (weak, nonatomic) IBOutlet UITextView *testoDetail;

@property (nonatomic, strong) Curiosita *curiosita;

@end

RecipeDetailViewController.m
Code:
- (void)viewDidLoad
{
    [super viewDidLoad];

self.titoloDetail.text = self.curiosita.titolo;
    self.testoDetail.text = self.curiosita.testo;
}

RecipeTableCell.h
Code:
@interface RecipeTableCell : UITableViewCell

@property (nonatomic, weak) IBOutlet UILabel *titoloLabel;
@property (nonatomic, weak) IBOutlet UILabel *testoLabel;

@end

My plist is:
http://awesomescreenshot.com/0422ozk7f2
http://awesomescreenshot.com/08f2ozkfbf

After all, I want to change data structure as it:
http://awesomescreenshot.com/05c2ozl51d

Someone can help me? Thanks a lot in advance!;)
 
I see this line of code in RecipeTableViewController.m
Code:
curiosita = [NSArray arrayWithObjects: curiosita1, curiosita2, nil];
But I don't see the variable, curiosita, declared anywhere except in RecipeDetailViewController.h

Do you get a compiler warning about that line or any other place in RecipeTableViewController.m where that variable is referenced?
 
I see this line of code in RecipeTableViewController.m
Code:
curiosita = [NSArray arrayWithObjects: curiosita1, curiosita2, nil];
But I don't see the variable, curiosita, declared anywhere except in RecipeDetailViewController.h

Do you get a compiler warning about that line or any other place in RecipeTableViewController.m where that variable is referenced?

Hi, app works and load without problems, I'm looking for better data management.

"curiosita" that you underlined is array's name on top of "RecipeTableViewController.m":
Code:
@implementation RecipeTableViewController

{
    NSArray *titoloArray;
    NSArray *testoArray;
    NSArray *curiosita;
    NSArray *searchResults;
}

;)
 
This seems to be fine data management. What I would do however, is exactly what you outlined in your post.

Construct your plist as you desired, and then access it like so (forgive typing errors):

Code:
NSArray *arr= [[NSArray alloc] initWithContentsOfFile:path];

NSMutableArray *arr2

for (NSDictionary *dict in arr) {
    Curiosita *cur = [Curiosita new];
    [cur setTitolo:dict[@"Titolo"]];
    [cur setTesto:dict[@"Testo"]];
    [arr2 addObject:cur];
}

curiosita = arr2;
 
This seems to be fine data management. What I would do however, is exactly what you outlined in your post.

Construct your plist as you desired, and then access it like so (forgive typing errors):

Code:
NSArray *arr= [[NSArray alloc] initWithContentsOfFile:path];

NSMutableArray *arr2

for (NSDictionary *dict in arr) {
    Curiosita *cur = [Curiosita new];
    [cur setTitolo:dict[@"Titolo"]];
    [cur setTesto:dict[@"Testo"]];
    [arr2 addObject:cur];
}

curiosita = arr2;

Hi and thanks for your answer!

I'm trying to follow your code but I have 3 problems:

1. how can I fill TableView? More deep, how can I fill
Code:
cell.titoloLabel.text = recipe.titolo;
cell.testoLabel.text = recipe.testo;

2. how can I fill
Code:
self.titoloDetail.text = self.curiosita.titolo;
self.testoDetail.text = self.curiosita.testo;

3. how can I make search bar work properly?

Thanks again! ;)
 
You would still be filling the cell text and the detail text the exact same way you were before, I was just showing you how to access the pList and fill your array. There are plenty of guides online about how to implement a search bar (controller). I won't recreate the wheel for you, but here you go Ray Wenderlich - How to add a search bar to a table view

Uhm, so I'm doing something wrong, because I get an empty table working as you suggested. I have to try more carefully, I guess.

Yeah, I know that tutorial: it's the same I have already implemented.

So, at the end, you tell me that I can fill cell text the exact same way I did.

Thanks for your help! :)
 
I would set a breakpoint at the beginning of the area where you start pulling stuff from the pList and check each component as you step through. Check that the arrays/dictionaries get filled as you would expect. Then also set a breakpoint for your cellForRowAtIndexPath method and see what happens there
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.