My current app consists of Navigation with Tabs, then a Table View in between, from the Table Rows when selected a Detail View is pushed. The issue I'm having is when I select a row it pushes to the Detail View and loads the html file in the Web View. However, when I navigate back and then select another row, it loads the same html from the previous selection. The only thing that stays relevant is the Title in the Navigation Title Bar.
Is this poor memory management on my part (I'm new to ObjC.. like only a week) or did I miss a step? I think me grabbing NSString *navDate = self.title; is my problem. Everything else basically works otherwise. Anyways, be gentle and thanks. :$
Table Cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellID = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID];
if(cell == nil){
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellID];
}
cell.textLabel.font = [UIFont systemFontOfSize:15];
cell.textLabel.text = [self.dateList objectAtIndex: [indexPath row]];
return cell;
}
Row Push
(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger row = [indexPath row];
if(self.aTextController == nil){
ATextController *aTextDetail = [[ATextController alloc] initWithNibName:#"ArchiveData" bundle:nil];
self.aTextController = aTextDetail;
[aTextDetail release];
}
aTextController.title = [NSString stringWithFormat:#"%#", [dateList objectAtIndex:row]];
SLESDAppDelegate *delegate = (SLESDAppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate.navigationController pushViewController:aTextController animated:YES];
}
DetailView
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *navDate = self.title;
NSString *null = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#", navDate] ofType:#"html"];
if(null != nil){
[webArchView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#", navDate] ofType:#"html"]isDirectory:NO]]]; }
else {
[webArchView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"error" ofType:#"html"]isDirectory:NO]]];
}
}
Since you are retaining the instance of ATextController and reusing it, you will have to execute the following snippet in viewWillAppear: -
NSString *navDate = self.title;
NSString *null = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#", navDate] ofType:#"html"];
if(null != nil){
[webArchView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#", navDate] ofType:#"html"]isDirectory:NO]]]; }
else {
[webArchView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"error" ofType:#"html"]isDirectory:NO]]];
}
The reason being that viewDidLoad is called once when the view controller loads its view. viewWillAppear: will be called every time the view is about to come on screen.
Related
i have a custom UItableView . i am loading data from a API and my main view are
i am loading data from a API .
My problem is,i have a left-side menu, i want to send a url when user select any menu acoording to select menu view will load.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath{
if(indexPath.row ==0){
appdataModel.newsApiUrl = homePagesUrl;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self.revealViewController revealToggleAnimated:YES];
ContactsTableViewController *vc = [[ContactsTableViewController alloc] initWithNibName:#"ContactsTableViewController" bundle:nil];
[self.navigationController pushViewController:contView animated:YES];
}else if (indexPath.row ==1){
appdataModel.newsApiUrl = jatioNews;
NSLog(#"here 1 :%#",appdataModel.newsApiUrl);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self.revealViewController revealToggleAnimated:YES];
ContactsTableViewController *vc = [[ContactsTableViewController alloc] initWithNibName:#"ContactsTableViewController" bundle:nil];
[self.navigationController pushViewController:contView animated:YES];
}
else if (indexPath.row ==2){
appdataModel.newsApiUrl = jatioNews;
NSLog(#"here 1 :%#",appdataModel.newsApiUrl);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self.revealViewController revealToggleAnimated:YES];
ContactsTableViewController *vc = [[ContactsTableViewController alloc] initWithNibName:#"ContactsTableViewController" bundle:nil];
[self.navigationController pushViewController:contView animated:YES];
}
}
#define homePagesNews #"http://198.72.115.125/~pratidin/api/topnews"
#define jatioNews #"http://198.72.115.125/~pratidin/api/categorynews/4"
here my api link . if user select Home-menu then view will load form homePagesNews API else user select second menu then view will from jatioNews API
from this code i am getting data
-(void)GetHomePageData{
NSString *urlString = [NSString stringWithFormat:#"%#",url];
NSURL *url = [[NSURL alloc]initWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response;
NSData *GETReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
res = [NSJSONSerialization JSONObjectWithData:GETReply options:NSJSONReadingMutableLeaves|| NSJSONReadingMutableContainers error:nil];
}
now i want when user select menu may home-menu or second-menu or third-menu according to user select url link will change and view will load in my ContactsTableViewController
my ContactsTableViewController viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
appdataModel = [AppDataModel getInstance];
appdataModel.newsApiUrl = homePagesUrl;
/**** for left side menu ***/
SWRevealViewController *revealViewController = self.revealViewController;
if ( revealViewController )
{
[self.sideBarButton setTarget: self.revealViewController];
[self.sideBarButton setAction: #selector( revealToggle: )];
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
/**** for Contractview***/
self.view.backgroundColor = [UIColor whiteColor];
NSString *path = [[NSBundle mainBundle] pathForResource:#"contacts" ofType:#"plist"];
contactsArray = [NSArray arrayWithContentsOfFile :path];
[self GetHomePageData];
[self.newsDataTableView reloadData];
}
some can tell me how can i solve my problem ... Thanks
Add a url property to ContactsTableViewController:
#interface ContactsTableViewController : UIViewController
#property NSURL *url;
...
#end
and in its viewDidLoad method you can load the data using whatever method you are using:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession]
dataTaskWithURL:self.url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Whatever
}];
Then set the URL from the tableview delegate method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath{
if (indexPath.row ==0){
appdataModel.newsApiUrl = homePagesUrl;
} else {
appdataModel.newsApiUrl = jatioNews;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self.revealViewController revealToggleAnimated:YES];
ContactsTableViewController *vc = [[ContactsTableViewController alloc] initWithNibName:#"ContactsTableViewController" bundle:nil];
vc.url = [NSURL URLWithString:appdataModel.newsApiUrl];
[self.navigationController pushViewController:vc animated:YES];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *customCell_Identifier = #"CustomCell";
ThreePartitionCells *cell = (ThreePartitionCells *)[tableView dequeueReusableCellWithIdentifier:customCell_Identifier];
if (cell == nil)
{
cell = (ThreePartitionCells *)[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:customCell_Identifier] autorelease];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ThreePartitionCells" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
NSLog(#"%#", [arrActivityList objectAtIndex:[indexPath row]]);
NSString *strTemp = [NSString stringWithFormat:#"%#-%#", [[[[[arrActivityList objectAtIndex:[indexPath row]] objectForKey:#"ITEMS"] objectForKey:#"Area"] objectForKey:#"AREANAME"] objectForKey:#"text"], [[[[[[[arrActivityList objectAtIndex:[indexPath row]] objectForKey:#"ITEMS"] objectForKey:#"Area"] objectForKey:#"ITEMS"] objectForKey:#"Bin"] objectForKey:#"BIN_BARCODE"] objectForKey:#"text"] ];
cell.lblProductName.text = strTemp;
cell.lblExpectedCount.text = [[[arrActivityList objectAtIndex:[indexPath row]]objectForKey:#"ProductName"]objectForKey:#"text" ];
cell.lblCounted.text = [[[arrActivityList objectAtIndex:[indexPath row]] objectForKey:#"Status"] objectForKey:#"text"];
[cell.lblProductName setFont:[UIFont fontWithName:#"Helvetica" size:13.0]];
[cell.lblCounted setFont:[UIFont fontWithName:#"Helvetica" size:13.0]];
return cell;
}
I get warning while analyzing project like this "value stored to 'cell' is never read" .Well! code is using the cell but outside of that if block. I want to silent this warning!
Can anybody help me for this?
Thanks in advance :)
The problem here:
if (cell == nil)
{
cell = (ThreePartitionCells *)[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:customCell_Identifier] autorelease];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ThreePartitionCells" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
You initialize the cell from custom class, and then you assigned to the cell from a nib, so that you lose control of the first cell and you have not used the first cell.
Try this:
if (!cell){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ThreePartitionCells"
owner:self
options:nil];
for (id obj in nib) {
if ([obj isKindOfClass:[ThreePartitionCells class]]) {
cell = (ThreePartitionCells *)obj;
break;
}
}
}
or:
if (!cell){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ThreePartitionCells"
owner:self
options:nil];
cell = nib[0];
}
or:
if (!cell){
cell = [[[ThreePartitionCells alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:customCell_Identifierr] autorelease];
}
I am trying (in vain) to reload tableView in MasterViewController from another View Controller SitesViewController. I use this code in the SitesViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = [[self tableView].indexPathForSelectedRow row];
//NSArray *appcell = [sitesMenu objectForKey:#"Table"];
NSLog(#"AppCell %#", sitesMenu);
NSDictionary *entry = [sitesMenu objectAtIndex:row];
self.siteid = [entry objectForKey:#"SITEID"];
NSLog(#" sample SiteView %#", siteid);
NDSClassMasterViewController *detailControllerTwo = [[NDSClassMasterViewController alloc] init];
detailControllerTwo.globalid = siteid;
NSLog(#"message %#", detailControllerTwo.globalid);
[detailControllerTwo fetchTweets];
dispatch_async(dispatch_get_main_queue(), ^{
[detailControllerTwo.tableView reloadData];
NSLog(#"%#", detailControllerTwo);
});
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
and this code for the method I am calling:
- (void)fetchTweets
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *siteurl = [[NSString alloc] initWithFormat:#"http://adhoc.nyxtek.co.za/spfjsonws/default2.aspx?siteid=%#", globalid];
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: siteurl]];
NSError* error;
menuItems = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
NSLog(#"%#", menuItems);
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
}
I have even added the reload code into the SiteViewController didSelectRow method.
I have read that I should add a property for it and synthesize but I have tried that but not sure how to add a property for UITableView to reference to the existing one.
The fetchTweets code runs, but the TableView doesn't reload.
Any assistance would be appreciated.
EDIT
This is the TableView code where I load the items in the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TweetCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//NSString *name = [[[menuItems objectForKey:#"Table"] objectAtIndex:0] objectForKey:#"MENUID"];
NSDictionary *tweet = [[menuItems objectForKey:#"Table"] objectAtIndex:indexPath.row];
//NSLog(#"%#", tweet);
NSString *text = [tweet objectForKey:#"MENUDESC"];
NSString *name = [tweet objectForKey:#"MENUDESC"];
NSLog(#"TEST 1%#", text);
cell.textLabel.text = text;
cell.detailTextLabel.text = [NSString stringWithFormat:#"by %#", name];
return cell;
}
Instead of exposing the table view via a property, why not simply write a function within the view controller that contains the code that would reload the data?
E.G. instead of:
[detailControllerTwo.tableView reloadData];
Declare a method in your MasterViewController that looks like:
- (void) updateTable
{
// tableView is declared as an IBOutlet
[tableView reloadData];
}
and then you can call that with:
dispatch_async(dispatch_get_main_queue(), ^{
[detailControllerTwo updateTable];
NSLog(#"%#", detailControllerTwo);
});
Hi I am new to iOS programming and I need a little help.
I have a table view cell which is populated by data from a .plist file. I need to be able to make a link within one of the cells. How could I do this?
Here is the code which is loading the data into the cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CustomTableCell";
static NSString *CellNib = #"DetailViewCell";
DetailViewCell *cell = (DetailViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (DetailViewCell *)[nib objectAtIndex:0];
}
cell.accessoryType = UITableViewCellAccessoryNone;
cell.cellTitleLabel.textColor = [UIColor blackColor];
cell.cellTitleLabel.font = [UIFont systemFontOfSize:20.0];
cell.cellSubtitleLabel.textColor = [UIColor darkGrayColor];
informations = [[NSArray alloc] initWithObjects:#"City", #"Country", #"State", #"History", #"Link", nil];
subtitles = [[NSArray alloc] initWithObjects:titleString, subtitleString, stateString, populationString, #"Link", nil];
cell.cellTitleLabel.text = [informations objectAtIndex:indexPath.row];
cell.cellSubtitleLabel.text = [subtitles objectAtIndex:indexPath.row];
return (DetailViewCell *) cell;
}
For the cell "Link" I need it to open a url which is stored in the .plist file. How could i do this?
Many thanks
Ryan
PS: I'm a newbie at this stuff, so be descriptive. Thanks
Firs of all, move the following to viewDidLoad
informations = [[NSArray alloc] initWithObjects:#"City", #"Country", #"State", #"History", #"Link", nil];
subtitles = [[NSArray alloc] initWithObjects:titleString, subtitleString, stateString, populationString, #"Link", nil];
Second, for the cell that has a value of #"Link"
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.cellTitleLabel.text == #"Link")
{
//Open in safari
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:cell.cellSubtitleLabel.text]];
}
}
Make the two arrays properties of your viewController.
#property (nonatomic, retain) NSArray *informationArray, *subtitlesArray;
Initialise them in your -viewDidLoad method:
self.informationArray = [NSArray arrayWithObjects:#"City", #"Country", #"State", #"History", #"Link", nil];
self.subtitlesArray = [NSArray arrayWithObjects:titleString, subtitleString, stateString, populationString, #"Link", nil];
and then check to see if the retrieved data is a link, then open it in safari.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
id title = [self.informationArray objectAtIndex:indexPath.row];
NSURL *link = [NSURL URLWithString:[self.subtitlesArray objectAtIndex:indexPath.row]];
//or to get the link out of a .plist
NSDictionary *plist = [NSData dataWithContentsOfFile:filePathForPlist];
NSURL *link = [NSURL URLWithString:[[plist objectForKey:title] objectForKey:#"Link"];
// you may need to get a different object from the .plist depending on the structure of the file.
//Check to see if the indexPath matches a cell with a title of "Link" and that the URL can be opened.
if([title isEqualToString:#"Link"] && [[UIApplication sharedApplication] canOpenURL:link]) {
[[UIApplication sharedApplication] openURL:link];
}
}
I am working for the first time in objective c and have come across an issue that I have not seen an answer for.
I am loading a set of data from a JSON data set and using it to populate a UITableView within a UITableViewController.
First when the view is loaded (viewDidLoad) I populate the array with the JSON data from a URL.
Next the data loads as it should. numberOfRowsInSection shows that there are 30 results in the array which is correct.
However The Iphone loads the entire set three times into the tableview.
Here is some code from the controller for that view:(Twitter is being used as an example and is not the actual data set I use)
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
//results = [[NSMutableArray alloc] init];
self.navigationItem.title=#"public_timeline";
self.tableView.allowsSelection = NO;
NSString *url = [[NSString alloc] init];
url = [[NSString alloc] initWithFormat:#"http://twitter.com/statuses/%s.json",#"public_timeline"];
if ([results count] == 0) {
[self parseJSON:url];
}
}
Here is the parseJSON (actual parse is done with the Cocoa JSON framework
-(void) parseJSON:(NSString *)URL{
NSURL *JSONURL = [NSURL URLWithString:URL];
NSData *responseData = [[NSData alloc] initWithContentsOfURL:JSONURL];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
results = [[NSMutableArray alloc] initWithArray:[responseString JSONValue]];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [results count];
}
then the cell's output
- (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];
// Set up the cell...
}
NSDictionary *cdict = [results objectAtIndex:indexPath.row];
cell.textLabel.text = [cdict valueForKey:#"text"];
return cell;
}
I am not sure if what I am doing is the best way to do this, so if someone could help me out that would be great.
Check the numberOfSectionsInTableView Method and change the return Value to 1
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}