Duplicate Method Issue - ios

I'm very new to Objective-C and the syntax and everything. I wrote two separate methods, but ran into the error: Duplicate declaration of method webView:shouldStartLoadWithRequest:navigationType:
So, it looks like I need to combine both of my webView:shouldStartLoadWithRequest:navigationType: methods. The only issue is, they both contain if statements and return values, and that super confused me. These are the two methods:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *full = [request.URL absoluteString];
if ([full isEqualToString:#"ExampleURL.com"] || [full isEqualToString:#"ExampleURL.com"]
|| [full isEqualToString:#"ExampleURL.com"] ) {
return YES;
}
else
return NO;
}
And:
-(BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *full = [request.URL absoluteString];
if ([full isEqualToString:#"ExampleURL.com"]) {
_backButton.hidden = YES;
return NO;
} else {
_backButton.hidden = NO;
}
return YES;
}
I've been trying to combine these two methods into one for a long time now, and am at a loss. It's the if statements that are tripping me up. Does anyone know how I could do this or what it would look like?
Side note: My desired goal is to only allow specific URLs to load. At the same time, I need the back button to be hidden only when one website is loaded. Does anyone know if there would be a way to hide / show the back button based on a URL by avoiding this method all together? I think I may be going about this wrong.

What's your desired logic here? One method will be called when the WebView starts loading. You will do some stuff, then return YES or NO based on whether you want the loading to proceed. You can't tell it it's ok to load and then tell it that it's not ok to load at the same time.
In your two methods you have this:
if ([full isEqualToString:#"ExampleURL.com"] || ...snipped... ) {
return YES;
}
And then this
if ([full isEqualToString:#"ExampleURL.com"]) {
// ...
return NO;
}
Which check the same thing but then return opposite values.
So I'll answer generally. This is sort of the general form of this method.
-(BOOL) webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
// alter application state
// return YES or NO
}
Lets say you want to do this, which I'm not sure is what you want, but this is the general idea:
if loading ExampleURL.com, then show the back button and allow the load
otherwise, hide the button and do not allow the load.
Then you might implement this method like so:
-(BOOL) webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
if ([[request.URL host] isEqualToString:#"ExampleURL.com"]) {
_backButton.hidden = NO;
return YES;
} else {
_backButton.hidden = YES;
return NO;
}
}
Now adjust that to reflect the logic you actually want.

I think you are trying to do something like this:
-(BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSString *full = [request.URL absoluteString];
if([full isEqualToString:#"hidebackbuttonforthiswebsite.com"])
_backButton.hidden = YES;
if ([full isEqualToString:#"AcceptedURL1.com"] ||
[full isEqualToString:#"AcceptedURL2.com"] ||
[full isEqualToString:#"AcceptedURL3.com"])
{
// Good URL, load it
return YES;
}
else
{
// Bad URL, so don't load it
return NO;
}
}
This will hide the back button for the specific URL, and then allow only a specific set of URLS to load. It sounded like this is what you want, but it's hard to understand your explanation.

I general, you might consider an additional conditional inside the method to determine what condition tree to use.
That could be another method called within this one.
You might also consider adding an additional argument to the method parameters if you need some criterion to determine conditional logic inside the method.
Another option, if you have two methods that cannot be merged because they do different things, but they have the same argument list, you should change the selectors (method signature) to distinguish them and make sure the selector indicates what they do differently.

Related

YTPlayerView once loaded opens the video in youtube app

So the title pretty much sums up the situation I am loading my YTPlayerView like this:
[self.videoView loadWithVideoId:#"youtube id"];
And like it was mentioned in the documentation it works perfectly however the second time I tap on the view the video opens on the youtube app sometimes and not on fullscreen.
Any help here ?
After a lot of research I didn't find an answer to this question so I decided to dig on the YTPlayerView.m file and see how the touch event is handled and I found that there is two ways to do this:
1- the YTPlayerView contains a webView and an override of:
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
This is the full code which checks the url scheme to trigger the appropriate action
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
if ([request.URL.host isEqual: self.originURL.host]) {
return YES;
} else if ([request.URL.scheme isEqual:#"ytplayer"]) {
[self notifyDelegateOfYouTubeCallbackUrl:request.URL];
return NO;
} else if ([request.URL.scheme isEqual: #"http"] || [request.URL.scheme isEqual:#"https"]) {
return [self handleHttpNavigationToUrl:request.URL];
}
return YES;
}
which was in my case this function handleHttpNavigationToUrl that returns a bool which indicates if the video should open on the app or the youtube application.
I have commented these lines that opens the video on the app and everything is ok now.
[[UIApplication sharedApplication] openURL:url];
return NO;
This is a quick fix and not good one i know but in my case i had no choice the 2nd solution is much better though.
2- The problem is in the youtube url in the first place as if you are using the embed url this problem will not occur,
so instead try to use other methods for loading the video by using the embed url, which is of the format:
http(s)://www.youtube.com/embed/[VIDEO ID]?[PARAMETERS]
so just try to use loadVideoByURL and use the embed url instead of loadWithVideoId.
Voila i hope this helps.

How can I prevent the webView from being visible till webViewDidFinishLoad is finished?

I'm removing content of the webView in the webViewDidFinishLoad. The problem is it first loads the page and shows all the content and then you will see the content I'm removing disappear. I would like it so that the user doesn't see anything disappear so the content should never been shown to the user.
This is my method :
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString* script = [NSString stringWithFormat:#"document.getElementById('menu').style.display='none';"];
[self.webView stringByEvaluatingJavaScriptFromString:script];
NSLog(#"gets");
}
The trick is use of isLoading property.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if(!webView.isLoading){
//Has completely stopped..
}
}
Use webview.hidden = YES till the time you dont want to see the data and then set it as no again
You can use the UIWebView Delegate methods as shown below.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
webView.hidden = YES;
return YES;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
webView.hidden = NO;
}
Isn't the same thing work in viewDidLoad ?
-(void)viewDidLoad{
NSString* script = [NSString stringWithFormat:#"document.getElementById('menu').style.display='none';"];
[self.webView stringByEvaluatingJavaScriptFromString:script];
NSLog(#"gets");
}

Is it possible to intercept the click handler in links of WEBUI's, and add a custom click action?

Say there's a custom link embedded in a WebUIView, and I would want to redirect a user not to Safari but to a different screen in the app. Is it possible to change the click handler for that link?
You can assign a delegate to the webView and use the webView:shouldStartLoadWithRequest:navigationType: method to detect the links you want a return NO.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if ([[request.URL absoluteString] isEqualToString:#"http://www.customurl.com"]) {
// Do something
return NO;
} else {
return YES;
}
}
You may also want to check the navigationType against UIWebViewNavigationTypeLinkClicked.

Checking the UIWebView's URL

So I have an image that I would like to hide only if my UIWebView is currently on a certain URL. For example, if "example1.com/cheese" was currently being displayed in my UIWebView, then I will hide the image. I have no idea how to go about checking to see if a specific URL is loaded in though. I'm trying this:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request {
NSString *host = [request.URL host];
if ([host != isEqualToString:#"example1.com/cheese"]) {
image.hidden = NO;
}
else
image.hidden = YES;
}
My issue lies within my if statement. I'm unsure of how to do a "is not equal to this URL". Does anyone know what I need to change or add to fix this?
Update: This is the code I'm working with now, the error appearing is Use of undeclared identifier, host.:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request {
if (![host isEqualToString:#"exampleURL.com/cheese"]) {
image.hidden = NO;
} else {
image.hidden = YES;
}
}
This is basic Objective-C (really C) syntax:
if (![host isEqualToString:#"someURL"]) {
// doesn't match
} else {
// does match
}
The ! means "not". It negates the result of the expression. Since isEqualToString: returns YES if the two strings are equal, the ! negates it to NO. If the two strings are not equal, the NO result gets negated to YES.
You can also do this:
// Hide image if host matches "someURL"
image.hidden = [host isEqualToString:#"someURL"];

UIWebView's scrolling after textfield focus

I have UIView and UIWebView on screen. When I click on text field in website, web view content is going up. How could I force UIView to move as well then?
You can subscribe to either the UIKeyboardWillShowNotification or the UIKeyboardDidShowNotification, and move your UIView when you receive the notification. This process is described here:
Text, Web, and Editing Programming Guide for iOS: “Moving Content That Is Located Under the Keyboard”
Maybe this helps: I didn't want the UIWebView to scroll at all, including when focusing on a textfield.
You have to be the delegate of the UIWebView:
_webView.scrollView.delegate = self;
And then add this method
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
scrollView.contentOffset = CGPointZero;
}
UIWebView has a callback:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
This is triggered whenever a new URL request is about to load. From javascript, you could trigger a new request URL on the onfocus event of the tag, with a custom schema like:
window.location = "webViewCallback://somefunction";
Here's a script to put your custom event inside any html page to load.
You'll have to get the whole HTML before loading it to the UIWebView like this:
NSString *html = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"your URL"] encoding:NSUTF8StringEncoding error:nil];
Then insert the following inside the HTML text in a appropriate place:
<script>
var inputs = document.getElementsByTagName('input');
for(int i = 0; i < inputs.length; i++)
{
if(inputs[i].type = "text")
{
inputs[i].onfocus += "javascript:triggerCallback()";
}
}
function triggerCallback()
{
window.location = "webViewCallback://somefunction";
}
</script>
Then, on the callback you should do something like this:
-(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if ( [[inRequest URL] scheme] == #"webViewCallback" ) {
//Change the views position
return NO;
}
return YES;
}
That's it. Hope it helps.
Wow, I had the same problem few days ago, it was really annoying. I figured out that window.yPageOffset is changing, but as far as I know there aren't any events to bind when it changes. But maybe it will help you somehow. ;-)
I think you overwrote scrollViewDidScroll wrong.
You need to implement custom class for UIWevView and overwrite scrollViewDidScroll:
- (void) scrollViewDidScroll:(UIScrollView *)scrollView{
[super scrollViewDidScroll:scrollView];
[((id<UIScrollViewDelegate>)self.delegate) scrollViewDidScroll:scrollView];
}

Resources