How do you pass data from a tableview Controller with sections to a ViewController? I can do it when I'm not using sections, but the program crashes when I use sections? And I don't understand.
This is the error message I get and it cranes with a SIGABIT message on this line:
NSString *mytempName = [NSString stringWithString:[tempObject charName]];
Error message:
2014-07-24 06:38:05.465 Passing_Data_With_Two_Sections[469:60b] -[__NSArrayM charName]: unrecognized selector sent to instance 0x8f0d230
2014-07-24 06:38:05.501 Passing_Data_With_Two_Sections[469:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM charName]: unrecognized selector sent to instance 0x8f0d230'
Here is the code from the TableView Controller
#import "myTableView.h"
#interface myTableView ()
#end
#implementation myTableView
NSMutableArray *myHeadersArray;
NSMutableArray *myFightersArray;
NSMutableArray *myLadiesArray;
NSMutableArray *myArray;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
myHeadersArray = [[NSMutableArray alloc]initWithObjects:#"Fighters", #"Ladies", nil];
myFightersArray = [[NSMutableArray alloc]init];
myLadiesArray = [[NSMutableArray alloc]init];
objectFile *myObject = [[objectFile alloc]init];
myObject.charName = #"Peter Pan";
[myFightersArray addObject:myObject];
myObject = [[objectFile alloc]init];
myObject.charName = #"Mikey Mouse";
[myFightersArray addObject:myObject];
myObject = [[objectFile alloc]init];
myObject.charName = #"Mrs Duck";
[myLadiesArray addObject:myObject];
myObject = [[objectFile alloc]init];
myObject.charName = #"Mini Mouse";
[myLadiesArray addObject:myObject];
myArray = [NSMutableArray arrayWithObjects:myFightersArray, myLadiesArray, nil];
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [myHeadersArray objectAtIndex:section];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [myHeadersArray count];
//This seems to crash if you go above 2. Which I assume is somehow tied in with the sections.
//Adding additional names now no longer crash. But if I changed it to myArray then it crashes
//bitching it being greater 2.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [myArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"myCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell" forIndexPath:indexPath];
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = ((myTempObjectFile*)[[myArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]).charName;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
ViewController *vc = [segue destinationViewController];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
int myrow = [path row];
myTempObjectFile *tv = [myArray objectAtIndex:myrow];
vc.tempObject = tv;
}
#end
And here is the code from my ViewController:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize myLabelOutput;
#synthesize tempObject;
- (void)viewDidLoad
{
NSString *mytempName = [NSString stringWithString:[tempObject charName]];
[myLabelOutput setText:mytempName];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
This happens because you try to invoke method charName for an array.
As I see you store arrays in array and you should change implementation to:
myTempObjectFile *tv = [[myArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]
vc.tempObject = tv;
or just
myTempObjectFile *tv = myArray[indexPath.section][indexPath.row]
vc.tempObject = tv;
This answer to your question.
But I think that here we need to refactor: not very beautiful to store arrays in an array, it is better to make an abstract object for this data structure. And tempObject name does not bear any semantic meaning.
Related
I am using the following code for showing the checkmarks in the uitableview
{
// NSArray *tableContents;
NSMutableArray *selectedMarks; // You need probably to save the selected cells for use in the future.
}
#property (strong, nonatomic) IBOutlet UITableView *languageTableView;
#property (nonatomic, strong) NSArray *tableContents;
#end
#implementation QPLanguageSettingsController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self initialisation];
selectedMarks = [NSMutableArray new];
}
#pragma mark - View Life Cycle
-(void)initialisation
{
_tableContents = [NSArray arrayWithObjects:#"English",#"Spanish",#"Russian",#"Arabic",#"Portuguese",#"French",#"German",#"German",#"German",#"German",#"German",#"German",#"German",#"German", nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITableView delegate & datasources
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 14;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"newFriendCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//etc.
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.textColor = [UIColor whiteColor];
cell.backgroundColor = [UIColor clearColor];
[cell setIndentationLevel:3];
[cell setIndentationWidth:10];
NSString *text = [_tableContents objectAtIndex:[indexPath row]];
//cell.isSelected = [selectedMarks containsObject:text] ? YES : NO;
cell.textLabel.text = text;
NSDictionary *item = [_tableContents objectAtIndex:indexPath.row];
if ([selectedMarks containsObject:item])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//if you want only one cell to be selected use a local NSIndexPath property instead of array. and use the code below
//self.selectedIndexPath = indexPath;
//the below code will allow multiple selection
NSDictionary *item = [_tableContents objectAtIndex:indexPath.row];
if ([selectedMarks containsObject:item])
{
[selectedMarks removeObject:item];
}
else
{
[selectedMarks addObject:item];
}
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
But the problem is that when i come again to the view controller all the checkmarks disappears. how to solve it. Remember i am using multiple selection in uitableview.
I tried the to get solution for your question.I got it successfully.It works perfectly.
This is sample one.Try this code.It works fine.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *tableViewCheckMarkPreviousSelectionUpdate;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *arrProductSelection,*arrProductSelectDeSelectCheckMark;
NSArray *arrayFetchFromDefaults;
}
#end
#implementation ViewController
#synthesize tableViewCheckMarkPreviousSelectionUpdate;
- (void)viewDidLoad
{
[super viewDidLoad];
arrProductSelection = [[NSMutableArray alloc]initWithObjects:#"iPhone",#"iPad",#"iPod",#"iTV",#"iWatch",#"iMac",nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewWillAppear:(BOOL)animated
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
arrayFetchFromDefaults = [userDefaults objectForKey:#"selectedcheckmark"];
arrProductSelectDeSelectCheckMark = [[NSMutableArray alloc]initWithArray:arrayFetchFromDefaults];
if(arrProductSelectDeSelectCheckMark.count == 0)
{
arrProductSelectDeSelectCheckMark = [[NSMutableArray alloc]init];
for(int j=0;j<[arrProductSelection count];j++)
{
[arrProductSelectDeSelectCheckMark addObject:#"deselected"];
}
}
[tableViewCheckMarkPreviousSelectionUpdate reloadData];
}
#pragma mark - UITableViewDataSource Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrProductSelection.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *strCell = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCell];
if(cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCell];
}
if([[arrProductSelectDeSelectCheckMark objectAtIndex:indexPath.row] isEqualToString:#"deselected"])
cell.accessoryType = UITableViewCellAccessoryNone;
else
cell.accessoryType = UITableViewCellAccessoryCheckmark;
cell.textLabel.text = [arrProductSelection objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - UITableViewDelegate Methods
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
#try
{
CGPoint touchPoint = [cell convertPoint:CGPointZero toView:tableViewCheckMarkSelectionUpdate];
NSIndexPath *indexPath = [tableViewCheckMarkSelectionUpdate indexPathForRowAtPoint:touchPoint];
NSLog(#"%#",arrProductSelectDeSelectCheckMark);
if([arrProductSelectDeSelectCheckMark count]==0)
{
for(int i=0; i<[arrProductSelection count]; i++)
{
[arrProductSelectDeSelectCheckMark addObject:#"deselected"];
}
}
if([[arrProductSelectDeSelectCheckMark objectAtIndex:indexPath.row] isEqualToString:#"deselected"])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[arrProductSelectDeSelectCheckMark replaceObjectAtIndex:indexPath.row withObject:#"selected"];
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
[arrProductSelectDeSelectCheckMark replaceObjectAtIndex:indexPath.row withObject:#"deselected"];
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:arrProductSelectDeSelectCheckMark forKey:#"selectedcheckmark"];
[defaults synchronize];
}
#catch (NSException *exception) {
NSLog(#"The exception is-%#",exception);
}
}
#end
You have multiple solutions:
Using a rational DB on the device like Core-data or SQLite which actually fits your use case but number 3 is more suitable for your use case.
Using NSUserDefaults:
At runtime, you use an NSUserDefaults object to read the defaults that your application uses from a user’s defaults database. NSUserDefaults caches the information to avoid having to open the user’s defaults database each time you need a default
You can find an example here. But NSUserDefaults is to save settings/config/setup information or perhaps user info and NOT for the use case you need.
Using NSCoder which is in my opinion fits your use case.
you can create a Singleton and store data on it :
Singleton.h
#interface Singleton : NSObject
#property (nonatomic, strong) NSArray *rowsChecked;
+ (Singleton *)sharedInstance;
+ (NSArray *)getRowsChecked;
+ (void)setRowsChecked:(NSArray *)rowsChecked;
#end
Singleton.m
#import "Singleton.h"
#implementation Singleton
static Singleton *sharedObject;
+ (Singleton *)sharedInstance;
{
if (sharedObject == nil) {
static dispatch_once_t pred;
dispatch_once(&pred, ^{
sharedObject = [[Singleton alloc] init];
});
}
return sharedObject;
}
+ (NSArray *)getRowsChecked
{
Singleton *singleton = [Singleton sharedInstance];
return singleton.rowsChecked;
}
+ (void)setRowsChecked:(NSArray *)rowsChecked
{
Singleton *singleton = [Singleton sharedInstance];
singleton.rowsChecked= rowsChecked;
}
#end
and to access to your Singleton :
[[Singleton sharedInstance] getRowsChecked]
// or
[[Singleton sharedInstance] setRowsChecked:anArray];
Use the following code:
#import "ViewController.h"
#interface ViewController ()<UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *languagesTableView;
#property (strong, nonatomic) NSArray *languagesArray;
#property (strong, nonatomic) NSMutableArray *checkMarksArray;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.languagesTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cell"];
self.languagesArray = [NSArray arrayWithObjects:#"English",#"Spanish",#"Russian",#"Arabic",#"Portuguese",#"French",#"German", nil];
self.checkMarksArray = [[NSMutableArray alloc]init];
if( [[NSUserDefaults standardUserDefaults]objectForKey:#"selectedRowsArray"])
{
self.checkMarksArray = [[[NSUserDefaults standardUserDefaults]objectForKey:#"selectedRowsArray"] mutableCopy];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.languagesArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *languagesCell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
languagesCell.textLabel.text = self.languagesArray[indexPath.row];
if([self.checkMarksArray containsObject:[NSNumber numberWithLong:indexPath.row]])
{
languagesCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
languagesCell.accessoryType = UITableViewCellAccessoryNone;
}
[[NSUserDefaults standardUserDefaults]setObject:self.checkMarksArray forKey:#"selectedRowsArray"];
[[NSUserDefaults standardUserDefaults]synchronize];
return languagesCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if([self.checkMarksArray containsObject:[NSNumber numberWithLong:indexPath.row]])
{
[self.checkMarksArray removeObject:[NSNumber numberWithLong:indexPath.row]];
}
else
{
[self.checkMarksArray addObject:[NSNumber numberWithLong:indexPath.row]];
}
[self.languagesTableView reloadData];
}
#end
Check this GitHub link:
https://github.com/k-sathireddy/TableViewSelectedCheckMarks
Here I have a Search Bar on the top of the UIViewController, and also a UITableView below the Search Bar.
When I don't Search things, the tableView could display things well, but when I search, the searchResultTableView can only show some white cell, not the correct result.
Here is the .h file:
#import <UIKit/UIKit.h>
#interface MySearchViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *myTableView;
- (void)reloadView;
#end
And here is the .m file:
#import "MySearchViewController.h"
#import "MyEventInfo.h"
#import "MyEventTableViewCell.h"
#import "MyEventDetailViewController.h"
#interface MySearchViewController ()
#property NSUserDefaults *usrDefault;
#end
#implementation MySearchViewController {
NSMutableArray *events;
NSArray *searchResults;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.usrDefault = [NSUserDefaults standardUserDefaults];
events = [[NSMutableArray alloc] init];
[self extractEventArrayData];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self reloadView];
}
- (void)reloadView {
NSLog(#"reloadView");
events = [[NSMutableArray alloc] init];
[self extractEventArrayData];
[self.myTableView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)extractEventArrayData {
NSArray *dataArray = [[NSArray alloc] initWithArray:[self.usrDefault objectForKey:#"eventDataArray"]];
for (NSData *dataObject in dataArray) {
MyEventInfo *eventDecodedObject = [NSKeyedUnarchiver unarchiveObjectWithData:dataObject];
[events addObject:eventDecodedObject];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.myTableView) {
return [events count];
} else {
NSLog(#"searchResults count:%lu",(unsigned long)[searchResults count]);
return [searchResults count];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 360;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomTableCell";
MyEventTableViewCell *cell = (MyEventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[MyEventTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Display MyEventTableViewCell in the table cell
MyEventInfo *event = nil;
if (tableView == self.myTableView) {
event = [events objectAtIndex:indexPath.row];
} else {
event = [searchResults objectAtIndex:indexPath.row];
NSLog(#"name of event:%#", event.nameOfEvent);
}
cell.nameOfEvent.text = event.nameOfEvent;
cell.imageOfEvent.image = [UIImage imageNamed:event.imageOfEvent];
cell.timeOfEvent.text = event.timeOfEvent;
cell.locationOfEvent.text = event.locationOfEvent;
cell.dateOfEvent.text = event.dateOfEvent;
return cell;
}
- (void)filterContentForSearchText:(NSString*)searchText
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"nameOfEvent contains[c] %#", searchText];
searchResults = [events filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString];
return YES;
}
#end
And on the storyboard I've already set the tableView's delegate and datasource to self. This drives me crazy, I cannot figure out what's wrong. Could someone help me out? Thanks.
when searching, cell's objects were all null, and had nothing in itself
when not searching, the cell is well with objects that had content the same as event
cannot delete the rows, am getting terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object
i have the following:
#import <UIKit/UIKit.h>
#class CSDetailViewController;
#interface CSMasterViewController : UITableViewController
#property (strong, nonatomic) CSDetailViewController *detailViewController;
#property (strong, nonatomic) NSMutableArray *kryeministrat;
#end
and the following at implementation:
#import "CSMasterViewController.h"
#import "CSDetailViewController.h"
#implementation CSMasterViewController
- (void)awakeFromNib
{
self.clearsSelectionOnViewWillAppear = NO;
self.preferredContentSize = CGSizeMake(320.0, 600.0);
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
NSString *path = [[NSBundle mainBundle]pathForResource:#"KryeministratList" ofType:#"plist"];
NSDictionary *kryeministratInfo = [NSDictionary dictionaryWithContentsOfFile:path];
self.kryeministrat = [kryeministratInfo objectForKey:#"kryeministrat"];
self.detailViewController = (CSDetailViewController *) [[self.splitViewController.viewControllers lastObject] topViewController];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.kryeministrat count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSDictionary *kryeministrat = self.kryeministrat[indexPath.row];
cell.textLabel.text = kryeministrat[#"name"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *kryeministrat = self.kryeministrat[indexPath.row];
NSString *urlString = kryeministrat[#"url"];
self.detailViewController.detailItem = urlString;
}
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.kryeministrat removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
#end
from your exception, you should look into this code:
NSDictionary *kryeministratInfo = [NSDictionary dictionaryWithContentsOfFile:path];
self.kryeministrat = [kryeministratInfo objectForKey:#"kryeministrat"];
Although property kryeministrat is declared as NSMutableArray , kryeministratInfo is NSDictionary. It means the values in the kryeministratInfo are all immutable.
SO you can do like:
NSDictionary *kryeministratInfo = [NSDictionary dictionaryWithContentsOfFile:path];
self.kryeministrat = [NSMutableArray arrayWithArray:[kryeministratInfo objectForKey:#"kryeministrat"]];
Basically what i want to do is i want to fill a table view with strings from an array. I've made a second UIviewcontroller and a custom cell with that show an image and two other labels. But when i run the code, there is no error messages but the tableview is blank, almost like its not recognizing the code at all. I have declared a delegate and datasource for it in the .h file.
#import "ViewController4.h"
#import "Cell.h"
#import "XMLparse.h"
#interface ViewController4 ()
#end
#implementation ViewController4
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(NSMutableArray *)objects {
if (!Datarray) {
Datarray = [[NSMutableArray alloc]init];
}
return Datarray;
}
- (void)viewDidLoad
{
[super viewDidLoad];
Datarray = [[NSMutableArray alloc]initWithObjects:#"USD",#"EUR",#"JPY",#"BGN",#"CZK",#"DKK",#"GBP",#"HUF",#"LTL",#"PLN",#"RON",#"SEK",#"CHF",#"NOK",#"HRK",#"RUB",#"TRY",#"AUD",#"BRL",#"CAD",#"CNY",#"HKD",#"IDR",#"ILS",#"INR",#"KRW",#"MXN",#"MYR",#"NZD",#"PHP",#"SGD",#"THB",#"ZAR", nil];
Tableview.delegate = self;
XMLparse *datee = [[XMLparse alloc]init];
[datee loadDataFromXML];
Date.text = [NSString stringWithFormat:#"Last updated: %#",[datee tid]];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableview:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableview numberOfRowsInSection:(NSInteger)section {
return [Datarray count];
}
- (CGFloat)tableView:(UITableView *)tableview heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 78;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"Cell";
Cell *cell = (Cell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"Cell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// cell.ratename.text = [tableData objectAtIndex:indexPath.row];
// cell.thumbnailImageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]];
cell.currencyname.text = [Datarray objectAtIndex:indexPath.row];
return cell;
}
#end
You have to set self to datasource property of UITableView. I suggest you the following code edited.
- (void)viewDidLoad
{
[super viewDidLoad];
Datarray = [[NSMutableArray alloc]initWithObjects:#"USD",#"EUR",#"JPY",#"BGN",#"CZK",#"DKK",#"GBP",#"HUF",#"LTL",#"PLN",#"RON",#"SEK",#"CHF",#"NOK",#"HRK",#"RUB",#"TRY",#"AUD",#"BRL",#"CAD",#"CNY",#"HKD",#"IDR",#"ILS",#"INR",#"KRW",#"MXN",#"MYR",#"NZD",#"PHP",#"SGD",#"THB",#"ZAR", nil];
Tableview.delegate = self;
Tableview.dataSource = self; // <---- added code for setting datasource.
XMLparse *datee = [[XMLparse alloc]init];
[datee loadDataFromXML];
Date.text = [NSString stringWithFormat:#"Last updated: %#",[datee tid]];
}
I'm trying to put together a simple app that lists all videos in the iPod library (movies, TV shows, etc) and allows the user to play any video they choose. The app is using a storyboard that has a NavigationController with the UITableView in it.
It looks like the query is actually getting the MPMediaItems, but the cells aren't being updated with the title of each movie. Can you take a look at this and tell me what I'm doing wrong?
Here's the .h:
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface MovieListViewController : UITableViewController
{
MPMediaQuery * _movieQuery;
NSArray * _movieArray;
}
#property (nonatomic,strong) MPMediaQuery *movieQuery;
#property (nonatomic,strong) NSArray *movieArray;
#end
And here's the .m:
#import "MovieListViewController.h"
#interface MovieListViewController ()
#end
#implementation MovieListViewController
#synthesize movieQuery = _movieQuery,
movieArray = _movieArray;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
MPMediaPropertyPredicate *predicate = [MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInteger:MPMediaTypeAnyVideo] forProperty:MPMediaItemPropertyMediaType];
MPMediaQuery *movieQuery = [[MPMediaQuery alloc] init];
[movieQuery addFilterPredicate:predicate];
NSLog(#"movieQuery got back %u results",[[movieQuery items]count]);
self.movieArray = [movieQuery items];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Dispose of any resources that can be recreated.
self.movieQuery = nil;
self.movieArray = nil;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
/*- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 0;
}*/
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(#"UITableView has %u rows",[self.movieArray count]);
return [self.movieArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
MPMediaItem *item = [[self.movieQuery items]objectAtIndex:[indexPath row]];
cell.textLabel.text = [item valueForProperty:MPMediaItemPropertyTitle];
return cell;
}
Issue is with this line:
MPMediaItem *item = [[self.movieQuery items]objectAtIndex:[indexPath row]];
Change that to:
MPMediaItem *item = [movieArray objectAtIndex:[indexPath row]];
You didn't added anything to movieQuery object, you created a local MPMediaQuery object in viewDidLoad and used that.
Another solution:
Change the viewDidLoad like:
- (void)viewDidLoad
{
[super viewDidLoad];
MPMediaPropertyPredicate *predicate = [MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInteger:MPMediaTypeAnyVideo] forProperty:MPMediaItemPropertyMediaType];
self.movieQuery = [[MPMediaQuery alloc] init];
[movieQuery addFilterPredicate:predicate];
NSLog(#"movieQuery got back %u results",[[self.movieQuery items]count]);
self.movieArray = [self.movieQuery items];
}