I am having a splitview application. MasterView is a UITableViewController and the detail view is web view. In the master pane on selecting an entry, another table view (created using one more tableviewcontroller to avoid complexity) appears and detail view shows some page related to the entry. This much is working fine.
Now I want the same with second table view as well i.e. on selecting an entry, the detail view should update accordingly. But its not getting updated. I have made the following function in the first tableViewController class:
-(void) display:(NSString*)theUrl
{
NSLog(#"%#", theUrl);
NSURL *myUrl = [NSURL URLWithString:theUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:myUrl];
splitViewDetailViewController *detailViewController =
self.detailViewController;
detailViewController.webView.scalesPageToFit = YES;
[detailViewController.webView loadRequest:request];
}
I am calling this function from the secondTableViewController and its getting called but detail view isn't getting updated.
In the didSelectRowAtIndex method of secondTableViewController I am doing this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *urlString=#"http://www.google.com";
NSURL *myUrl = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:myUrl];
splitViewSecondViewController *secondDetailViewController = [[splitViewSecondViewController alloc] init];
secondDetailViewController.detailViewController=self.detailViewController;
[self.navigationController pushViewController:secondDetailViewController animated:YES];
self.detailViewController.webView.scalesPageToFit = YES;
[self.detailViewController.webView loadRequest:request];
}
But then the following run time error comes:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSCFConstantString stringByAppendingString:]: nil argument
TableViewController.h
#protocol TableViewControllerDelegate
-(void)display:(NSString*)theUrl :(NSInteger)index;
#end
id<tableViewControllerDelegate>_delegate;
#property(nonatomic,assign) id<tableViewControllerDelegate>_delegate;
TableViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedIndex = indexPath.row;
[self.ResultTbl reloadData];
[_delegate display:(NSString*)theUrl :selectedIndex];
}
masterview(splitview).h
#import "tableViewController.h"
#interface MasterViewController : UIViewController <tableViewControllerDelegate>
masterview(splitview).m
-(void)display:(NSString*)theUrl :(NSInteger)index
{
NSLog(#"%#", theUrl);
NSURL *myUrl = [NSURL URLWithString:theUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:myUrl];
splitViewDetailViewController *detailViewController = self.detailViewController;
detailViewController.webView.scalesPageToFit = YES;
[detailViewController.webView loadRequest:request];
}
Related
I'm creating an app which has a webview. When user click to a link or a button in the webview, I want to be able to get the new url, and edit the new url.
shouldStartLoadWithRequest should do the trick, but that method is never called when I click to a link. I cannot find why this doesn't work.
I have read somewhere that I need to add this line :
webView.delegate = (id)self;
I tried it, and still get the same issue. Please help
AppDelegate.m
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *currentURL = [[request URL] absoluteString] ;
NSLog(#"Url: %#", currentURL);
return YES;
}
Controller.m
- (void)viewDidLoad
{
webView.delegate = (id)self;
NSString *tokenString = #"123";
[super viewDidLoad];
NSString *fullURL = [[NSString alloc] initWithFormat:#"http://192.168.1.69:8888/webapp/test.php?uid=%#", tokenString];
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
}
If your Controller instance adds itself as the delegate then the method you add to the AppDelegate instance will never be called.
Move the shouldStartLoadWithRequest method into your Controller class.
You've set your view controller as the web view's delegate. But then you've implemented the UIWebView delegate method in our application's delegate instead.
Try implementing that delegate method in your view controller. Your view controller is your web view's delegate.
So I am working on a vital update to an app I have on the appstore. I have an app with a tab bar and a nav controller. When the user selects an item from the list it sends the link it is getting from the xml file sent from my server to a detail view controller that is only a web view. The problem I'm having is when the user goes back to the tableview which is the root view for that tab the detail view isn't being released. When you select the other options in the app, the detail view doesn't change. It's not that my data isn't being released from the uishared application data but its the view isn't releasing. I know that there are many similar items like this on here and i've tried all of them. I will give you some of my code and greatly appreciate other tips and tricks. Im 15 and just getting into development so any info helps. Heres the code i think is necessary for anyone to help.
TableViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
NSString * storyLink = [[stories objectAtIndex: storyIndex] objectForKey: #"link"];
// clean up the link - get rid of spaces, returns, and tabs...
storyLink = [storyLink stringByReplacingOccurrencesOfString:#" " withString:#""];
storyLink = [storyLink stringByReplacingOccurrencesOfString:#"\n" withString:#""];
storyLink = [storyLink stringByReplacingOccurrencesOfString:#" " withString:#""];
videoDetailViewController.title = #"Videos";
ExampleAppDataObject* theDataObject = [self theAppDataObject];
theDataObject.videoData = storyLink;
if (self.videoDetailViewController == nil)
{
VideoDetailViewController *aBookDetail = [[[VideoDetailViewController alloc] initWithNibName:#"VideosDetailView" bundle:[NSBundle mainBundle]] autorelease];
self.videoDetailViewController = aBookDetail;
[aBookDetail release];
aBookDetail = nil;
}
[self.navigationController pushViewController:videoDetailViewController animated:YES];
}
DetailViewController:
#import "VideoDetailViewController.h"
#import "RSSEntry.h"
#import "ExampleAppDataObject.h"
#import "AppDelegateProtocol.h"
#implementation VideoDetailViewController
#synthesize activityIndicator;
#synthesize webView;
#synthesize pasteboard;
- (ExampleAppDataObject*) theAppDataObject;
{
id<AppDelegateProtocol> theDelegate = (id<AppDelegateProtocol>) [UIApplication sharedApplication].delegate;
ExampleAppDataObject* theDataObject;
theDataObject = (ExampleAppDataObject*) theDelegate.theAppDataObject;
return theDataObject;
}
- (void)viewDidLoad
{
ExampleAppDataObject* theDataObject = [self theAppDataObject];
NSString *urladdress = theDataObject.videoData;
NSURL *url = [NSURL URLWithString:urladdress];
NSURLRequest *requestobj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestobj];
pasteboard = [UIPasteboard generalPasteboard];
[super viewDidLoad];
}
- (void)dealloc
{
[webView release];
webView = nil;
[activityIndicator release];
[pasteboard release];
[VideoDetailViewController release];
[urlData release];
urlData = nil;
[super dealloc];
}
#end
I skipped a lot of the code that i didnt feel was necessary. If you want the actual files then email me at evan.stoddard#me.com
Don't release the webview in the detailViewController page, instead, put
[webView loadRequest:requestobj]; in in viewDidAppear(), not viewDidLoad
Also:
One way to make the transition smoother, change:
if (self.videoDetailViewController == nil) {
VideoDetailViewController *aBookDetail = [[[VideoDetailViewController alloc] initWithNibName:#"VideosDetailView" bundle:[NSBundle mainBundle]] autorelease];
self.videoDetailViewController = aBookDetail;
[aBookDetail release];
aBookDetail = nil;
}
[self.navigationController pushViewController:videoDetailViewController animated:YES];
Should be:
VideoDetailViewController *aBookDetail = [[VideoDetailViewController alloc] initWithNibName:#"VideosDetailView" bundle:[NSBundle mainBundle]] ;
[self.navigationController pushViewController:videoDetailViewController animated:YES];
[aBookDetail release];
Thanks to Anna Billstrom, I realized that I also should be using viewDidAppear instead of viewDidLoad. This is because I am passing data to the controller through an external data class when an item is selected from the table view. Therefore, the detail view controller is loading before there is data to load from the external data class. viewDidAppear solves this problem by getting data once the view loads after the cell is selected and there is data in the external class.
new to this site, but my head is absolutely killing me after trying for the past few hours to fix something that I know has to be insanely simple.
Short story:
I have a UIViewController with a UINavigationController
The UIViewController (tableView) is a UITableView that parses and displays RSS feed stories
There is a second UIViewController (newsWebView) with a UIWebView that gets pushed by the UINavigationController and is meant to display each story as the user clicks on rows in tableView
When the user is done with the UIWebView, they are pushed back to the first view, tableView
I have everything working except for the push of each row's URL to the webView in the second controller. It pushes the view, but the URL just isn't getting sent to the second controller so the webView is blank. The NSLogs I have in the code indicate that the URL is being created successfully, too, so what do I need to do to get newsWebView to handle the URL?
tableView.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
NSString * storyLink = [[stories objectAtIndex: storyIndex] objectForKey: #"link"];
// clean up the link - get rid of spaces, returns, and tabs...
storyLink = [storyLink stringByReplacingOccurrencesOfString:#" " withString:#""];
storyLink = [storyLink stringByReplacingOccurrencesOfString:#"\n" withString:#""];
storyLink = [storyLink stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"storyLink: %#", storyLink);
if (storyLink != nil && ![storyLink isEqualToString:#""]) {
// Wrapping the troublesome call with logs so you should be able to see if this is the line that is killing your app
NSLog(#"about to create url");
NSURL *url = [NSURL URLWithString:storyLink];
NSLog(#"creating url was successful");
//URL Request Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView
newsWebView *detailViewController = [[newsWebView alloc] initWithNibName:#"newsDetailWebView" bundle:nil];
//detailViewController.item = [[stories objectAtIndex: storyIndex] objectForKey: #"link"];
[self.navigationController pushViewController:detailViewController animated:YES];
//[detailViewController loadRequest:requestObj];
[detailViewController release];
}
}
So, what do I need to add to viewDidLoad in newsWebView.m? Or, for that matter, what is wrong with my tableView's didSelectRowAtIndexPath?
newsWebView.m
- (void)viewDidLoad {
}
Thank you very, very much. I need to take some Advil!
Have an instance variable say urlObject of NSUrl type in your newsWebView class. Make sure you add #property and #synthesize the object.
then
newsWebView *detailViewController = [[newsWebView alloc] initWithNibName:#"newsDetailWebView" bundle:nil];
newsWebview.urlObject = url;
[self.navigationController pushViewController:detailViewController animated:YES];
//[detailViewController loadRequest:requestObj];
[detailViewController release];
And in newsWebView.m
- (void)viewDidLoad {
[webView loadRequest:[NSURLRequest requestWithURL:urlObject]];
}
DetailViewController.m
Code:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *navTitle = self.navigationItem.title;
NSString *stalklabel = self.labelforurl.text;
NSLog(#"%#", stalklabel);
NSURL *address = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.twostepmedia.co.uk/json.php?q=%#",stalklabel]];
responseData = [[NSMutableData data] retain];
NSURLRequest *request = [NSURLRequest requestWithURL:address];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
//NSString *address = [NSString stringWithFormat:#"http://www.twostepmedia.co.uk/json.php?q=%#",na];
//[self initiateRequest:address];
//NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:address]];
//[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
RootViewController.m
Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//Initialize the detail view controller and display it.
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:dvController animated:YES];
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
dvController.navigationItem.title=[[managedObject valueForKey:#"data"] description];
dvController.labelforurl.text = [[managedObject valueForKey:#"data"] description];
[dvController release];
dvController = nil;
}
The output of NSLOG is "Label"?? So when i try and embed it in the URL, it only comes back with "Label"??
Any ideas?
In InterfaceBuilder, or somewhere in code, your labelforurl has a value of Label. Change this value for a different result. If you want to change it in IB, use a UITextField instead of a UIlabel.
So i'm building a webView into my application to show the contents of a URL that I am passing from a selection in a UITableView. I know the UIWebView is loading content properly because if you hard code say http://www.google.ca into the NSURL then it loads fine, however when I'm passing the URL that I parsed from an RSS feed back from the UITableView it won't load the URL properly. I tried the debugger and the URL is coming out as nil right before I try and parse it, however I can use NSLog to print the value of it out to the console.
here's the code in my UIViewController that has my UIWebView
#import <UIKit/UIKit.h>
#interface ReadFeedWebViewController : UIViewController
{
NSString *urlToGet;
IBOutlet UIWebView *webView;
}
#property(nonatomic, retain) IBOutlet UIWebView *webView;
#property(nonatomic, retain) NSString *urlToGet;
#end
Here's the code for my implementation's viewDidLoad method...
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Url inside Web View Controller - %#", urlToGet);
NSURL *url = [NSURL URLWithString:urlToGet];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:requestObj];
}
Once again, I can print the URL to NSLog fine and if I hard code the URL into the NSURL object then it will load fine in the UIWebView. Here is where I'm setting the value in my UITableViewController...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ReadFeedWebViewController *extendedView = [[ReadFeedWebViewController alloc] init];
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
extendedView.urlToGet = [[stories objectAtIndex: storyIndex] objectForKey:#"link"];
//NSLog([[stories objectAtIndex: storyIndex] objectForKey:#"summary"]);
NSLog([[stories objectAtIndex: storyIndex] objectForKey:#"link"]);
[self.navigationController pushViewController:extendedView animated:YES];
[extendedView release];
}
However, since I can print the value using NSLog in the extendedView view controller I know it's being passed properly. Cheers
The urlToGet is null into your ReadFeedWebViewController in the viewDidLoad method because when this method is call this variable is not yet affected. The viewDidLoad is call when the initialisation of the ViewController is finished.
I should you to call it in the viewWillAppear method like that:
- (void)viewWillAppear:(BOOL)animated {
NSURL *url = [NSURL URLWithString:urlToGet];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:requestObj];
}
Also, there is a memory leak in your code. You should release extendedView after pushing it on the navigation controller.
ReadFeedWebViewController *extendedView = [ReadFeedWebViewController new];
if (extendedView != nil) {
... setup extendedView here ...
[self.navigationController pushViewController:extendedView animated:YES];
[extendedView release];
}
Try this
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:20.0];