I'm building an iOS app.
I have HTML content in a UIWebView with hyperlinks, and I'm unable to open a link to another UIWebView.
I used UIWebView as a subview of ViewController. Here is the code:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
switch (navigationType) {
case UIWebViewNavigationTypeLinkClicked: { //this is when a user tap is detected
//write the handling code here.
isWebViewLoaded = false; //set this to false only if you open another view controller.
return NO; //prevent tapped URL from loading inside the UIWebView.
}
// some other typical parameters within a UIWebView. Use what is needed
case UIWebViewNavigationTypeFormResubmitted: return YES;
case UIWebViewNavigationTypeReload: return YES;
//for all other cases, including UIWebViewNavigationTypeOther called when UIWebView is loading for the first time
default: {
if (!isWebViewLoaded) {
isWebViewLoaded = true;
return YES;
}
else
return NO;
}
}
}
You only need to segue to a new controller with a web view, and pass the request to it. So something like this in your first case,
case UIWebViewNavigationTypeLinkClicked: { //this is when a user tap is detected
[self performSegueWithIdentifier:#"Next" sender:request];
isWebViewLoaded = false; //set this to false only if you open another view controller.
return NO; //prevent tapped URL from loading inside the UIWebView.
}
Notice that the sender argument in performSegueWithIdentifier:sender: is the request returned by the delegate method. Pass this request to a property in the view controller you're segueing to,
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(NSURLRequest *)sender {
NextViewController *next = segue.destinationViewController;
next.request = sender;
}
Finally, use that request to load the web view in NextViewController.
Related
I've implemented a view controller which is displaying a WKWebView. The web view displays certain pages containing links with a tags, e. g.:
<a id="dien10000513721" href="/ge/tr/issue.html" class="dien">Issue</a>
I would like to add a preview to these links by activating 3d-Touch in the web view, but the delegate method webView:shouldPreviewElement: is never called, when I run my app on a iPhone 7 with iOS 11 and doing a force touch on that link.
When I've created my web view and set the necessary properties with
theWebView.navigationDelegate = self;
theWebView.UIDelegate = self;
theWebView.allowsLinkPreview = YES; // Setting this to NO doesn't help
self.webView = theWebView;
The three delegate methods for previewing are implemented as dummies:
- (BOOL)webView:(WKWebView *)inWebView shouldPreviewElement:(WKPreviewElementInfo *)inElementInfo {
NSLog(#"url = %#", inElementInfo.linkURL);
return NO;
}
- (UIViewController *)webView:(WKWebView *)inWebView previewingViewControllerForElement:(WKPreviewElementInfo *)inElementInfo defaultActions:(NSArray<id<WKPreviewActionItem>> *)inPreviewActions {
return nil;
}
- (void)webView:(WKWebView *)webView commitPreviewingViewController:(UIViewController *)previewingViewController {
NSLog(#"");
}
Do I still have to perform any important configuration steps? What else could prevent the execution of 3D touch events?
I am loading a url in UIWebView in iOS. the url contains a button. I want to call a objective C method, when i click on this button. Please help.
This is source code
NSString *strUrl = #"<html><body><button type=\"button\" id=\"success_id\" style=\"width:200px;margin:0px auto;text-align:center; background:#1B2F77;color:#fff;padding:10px;font-size:10px;border:0px;\" name=\"continue\" onclick=\"ok.performClick();\">Continue</button></body></html>";
[_tempWebView loadHTMLString:strUrl baseURL:nil];
I want to load this string to UIWebview and When I click on button , then I want to open my own viewcontroller.
You need to do three things:
Override shouldStartLoadWithRequest delegate method of UIWeBView.
shouldStartLoadWithRequest method returns a bool value so return false, then it will not load the link.
Inside this method write whatever functionality you want to perform.
If it is your page, communicate with app via JavaScript otherwise you can override shouldStartLoadWithRequest method and check if this specific request is called
some code:
- (BOOL)isItThatButtonEvent:(NSURLRequest *)req {
if([req.URL.absoluteString isEqualString:#"that.specific.url.or.some.other.way.to.check.that"]) {
return YES;
}
return NO;
}
#pragma mark UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if([self isItThatButtonEvent:request]) {
[self methodThatOpensYourViewController];
return NO;
}
return YES;
}
I have webview and a Go-Back button for webview.
I need two functionality from Go-back button(as in standard browser)
Button should be disabled when it is not possible to go back
When pressed, should go back
Disabling the button is achieved by cocoa binding.
And go back action is done by binding following selector from Owner class
- (IBAction)buttonPressed:(id)sender {
[_webView goBack];
}
Since the buttonPressed: selector is only calling goBack selector, can I bind self.webView.goback to the button, eliminating the need of buttonPressed selector in owner class.
You can use following code Disabling your button
- (void)webViewDidFinishLoad:(UIWebView *)webView;{
if ([webView canGoBack]) {
_button.enabled = NO;
}else{
_button.enabled = YES;
}
}
iOS unfortunately doesn't have a dropdown picker like html does with the tag. I decided that I was finally going to create one for my app, and it looks and works great. My dropdown object is a subclass of UITextField. However, I changed something and now it only works some of the time.
User interaction is enabled, but I don't want the textfield to be editable. The class in which my dropdown subclass resides is UITextField delegate, and should receive delegate methods for UITextField.
I have - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ where I check to see if the textfield in question is a dropdown menu, and if it is, I call a method to instantiate a popover and disable editing, but the dropdown only appears on every other tap.
For example, i'll tap the "textfield" and my popover displays. I tap out so the popover goes away, then I tap on the "textfield" and nothing happens. I tap on the textfield once again and the popover appears. No idea why this is happening, here is what i'm doing:
.h
subclass : UIViewController<UITextFieldDelegate>
.m
dropdownTextField.delegate = self;
...
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
if(textField == self.measurementSelect){
NSLog(#"IM CALLED");
[self showPopover:textField];
return NO;
}
return YES;
}
-(void)showPopover:(id)sender{
if (_measurementPicker == nil) {
_measurementPicker = [[iPadMeasurementSelect alloc] initWithStyle:UITableViewStylePlain];
_measurementPicker.delegate = self;
}
if (_measurementPopover == nil) {
_measurementPopover = [[UIPopoverController alloc] initWithContentViewController:_measurementPicker];
[_measurementPopover presentPopoverFromRect:self.measurementSelect.frame inView:self.conversionView permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}
else {
[_measurementPopover dismissPopoverAnimated:YES];
_measurementPopover = nil;
}
}
Every tap gets nslogged, so I assume my popover method is the culprit of this problem. Any ideas?
Let's rewrite by teasing apart existence of the UI elements and the visible state of the popover:
// canonical lazy getters for UI elements
- (iPadMeasurementSelect *)measurementPicker {
if (!_measurementPicker) {
_measurementPicker = [[iPadMeasurementSelect alloc] initWithStyle:UITableViewStylePlain];
_measurementPicker.delegate = self;
}
return _measurementPicker;
}
- (UIPopoverController *)measurementPopover {
if (!_measurementPopover) {
_measurementPopover = [[UIPopoverController alloc] initWithContentViewController:self.measurementPicker];
}
return _measurementPopover;
}
// now the show/hide method makes sense. it can take a bool about whether to show or hide
-(void)showPopover:(BOOL)show {
if (show) {
[self.measurementPopover presentPopoverFromRect:self.measurementSelect.frame inView:self.conversionView permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
} else {
[self.measurementPopover dismissPopoverAnimated:NO];
// if you want/need to create a new one each time it is shown, nil the popover here, like this:
// self.measurementPopover = nil;
}
}
When the textField begins editing, show the popover like this:
[self showPopover:YES];
And when the delegate gets the didEndEditing message:
[self showPopover:NO];
I have a UIWebView that I use to load a webpage. I also have navigation buttons so you can go back and forward between previous pages loaded. Is there a way to hide the navigation buttons when there is no previous webpage?
Check here: Why is UIWebView canGoBack=NO in iOS7?
You can enable/disable your navigation buttons in the shouldStartLoadWithRequest method with canGoBack and canGoForward methods on UIWebView:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
if ([webView canGoBack])
{
[_browserBackItem setEnabled:YES];
}
else
{
[_browserBackItem setEnabled:NO];
}
if ([webView canGoForward])
{
[_browserForwardItem setEnabled:YES];
}
else
{
[_browserForwardItem setEnabled:NO];
}
return YES;
}
I'm not aware of anything built in to UIWebView that allows this but maybe you could try keeping track of the pages with a variable.
Every time a url request is made the UIWebView delegate method gets called and you could increment the variable there (see here). Then decrement the variable once the user has selected the back button.
Hope that helps.
you can save the loaded pages in an NSArray for example and test if that array is empty you hide the button.
to know the opened pages, you implement the UIWebViewDelegate in your class, and in the – webView:shouldStartLoadWithRequest:navigationType: callback you save the url.