UIWebView in UIScrollView and touch notifications - ios

I have view controller with following view hierarchy:
UIView
'- UIScrollView
'- UIWebView
'- UIWebView
'- ... more UIWebViews
UIScrollView has paging enabled and each page contains one UIWebView. UIScrollView occupies entire screen, UIWebView as well.
Now my problem is that I need to detect touches on entire screen. I guess that UIScrollView somehow eats most of those (and since UIWebView contains scroll view as well, things got even more complicated).
I tried subclassing each of those views and tried both touchesBegan and tap gesture recognizer but nothing. All I was able to get was very unreliable gesture recognizer on UIWebView, it worked once in 20 taps, very random and very weird.
How should I solve this? I need touchesBegan and touchesEnded or tap gesture.

I think you'll need to find an alternative way of building your UI. Apple explicitly recommend against embedding scroll views inside scroll views:
You should not embed UIWebView or
UITableView objects in UIScrollView
objects. If you do so, unexpected
behavior can result because touch
events for the two objects can be
mixed up and wrongly handled.
Without knowing what you're trying to achieve it's difficult to be able to suggest a valid alternative. Tabs? A swipe gesture at the bottom of the screen? Links inside the webviews?

You can do that, but you need to be careful with the touch events so that scrollview does not handle touches intended for webview.
Import line on the code below is [[[wv1 subviews] lastObject] setScrollEnabled:NO];
for (NSString *link in links) {
UIWebView *wv1 = [[UIWebView alloc] initWithFrame:frame];
NSURL *aurl = [site getUrl:link local:YES];
[wv1 loadRequest:[NSURLRequest requestWithURL:aurl]];
[[[wv1 subviews] lastObject] setScrollEnabled:NO];
[scrollView addSubview:wv1];
[wv1 release];
}

Related

Forwarding a gesture to superview

So I have got this scenario:
-NavigationController
-PageViewController
-MapViewController
-UIView
-MKMapView (Full Screen)
-OtherViewController
So basically, I want it to switch pages (viewcontrollers) when catching the UIScreenEdgeGesture. But having the map in one of them, this doesn't work properly.
I have researched a lot (!) about this but still haven't found the right solution.
I believe that the correct approach here is to delegate this gesture to the nextResponder in the hierarchy.
So I have successfully captured the gesture when the user swipes on the left edge of the screen.
Right now my issue is I can't manage to pass the gesture to the UIView (MKMapView.superview).
I have two questions :
// 1. How to do it
// 2. Is this the right approach?
Let me know your thoughts on this one please!
EDIT 1:
Adding some code and Images of story board
UIScreenEdgePanGestureRecognizer *popRecognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:[self.view superview] action:#selector(handlePopRecognizer:)];
popRecognizer.edges = UIRectEdgeLeft;
popRecognizer.delegate = self;
[self.mapView addGestureRecognizer:popRecognizer];
EDIT 2: I want this behaviour : Use UIScreenEdgePanGestureRecognizer without moving MKMapView
But when the gesture is recognized, I want it to switch to the page on the left (OtherViewController)
FINAL EDIT: THE workaround that I've come up with consists in putting a clear view on top of the map, leading to the desired behaviour. Not happy with the solution, but it works for now.
When you create your gesture, make the target the superview, and call the method in the superview for the action, something like:
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:[self.view superview] action:#selector(swipeHandler:)];
Don't know if MKMapView.superview would work, that depends on if MKMapView is an instance. Hard to know what you're referring to without code.

forward touch events to UIWebView from overlaying UIView / how to make touch events to uiwebview from code

Imagine a UIWebView that is partly overlayed by a UIView which itself has to receive touches.
All I want to do is forward the touch events from the overlaying UIView to the UIWebView. I tried subclassing the UIView and forward the touches to UIWebView like
[webview touchesbegan:touches withEvent: event]
but it isn't working.
Well, it works as far as I can see by subclassing the UIWebView that touchesbegan gets called. But this never happens when I touch the UIWebview directly so this is obviously not the right way to do this. Sooo, what am I doing wrong?
You can do this by using the javascript
NSString *javaScript = #"document.getElementById('id_username').value = 'tfusername'";
to set value on any of the data
You can send click on any object by fetching its Id
and then by evaluating it to send event.
NSString *myval = [webView stringByEvaluatingJavaScriptFromString:#"document.querySelector('input[type=\"submit\"][value=\"Log in\"]').click();"];
May be this is what you are asking for. Thanks

How can you handle touching a link within a UIWebView when you have a UIView overlay directly on top of it?

I've been researching how to use a UIWebView embedded in a UIScrollView for a while now and cant seem to find an easy fix to my problem. I'm using a UIWebView because a UITextView, although allowing hyperlinks, does not allow you to change the link color from the standard blue apple sets.
But using a UIWebView introduces another problem: It blocks the UIScrollView it is embedded in from handling scroll events because a UIWebView handles these events within its own private implementation.
Although this allows me to use its embedded links, the UIWebView absorbs the touch events which doesn't allow me to scroll up/down when dragging within the UIWebView itself. I worked around this problem by placing a transparent UIView overlay exactly over the UIWebView, intercepting the touch events that it receives, and resigning it as first responder so that the UIScrollView that they are both subviews of can handle the scrolling appropriately.
Now, however, I can't seem to think of solution to the new problem this introduces: I can't click on the links within my UIWebView that is right under the UIView Overlay.
What is the best way to forward touch events to a UIWebView that is right underneath my transparent UIView in order to trigger my UIWebView's delegate method 'webView:shouldStartLoadWithRequest:navigationType:' for tapping on links?
FYI from UIWebView API doc:
Important: You should not embed UIWebView or UITableView objects in UIScrollView objects. If you do so, unexpected behavior can result because touch events for the two objects can be mixed up and wrongly handled.
Back to the question,
UIWebView has property called scrollView, try doing:
webView.scrollView.scrollEnable = NO;

Stop UIView being dragged around screen

We are integrating a third party offer wall into our iOS phonegap app.
When we show the offerwall it gets added to the standard phonegap viewcontroller and shows over the top of our webview.
The problem with it is that people can drag the view all over the place so instead of just scrolling up and down in place. Which gives the effect show in the screenshot below:
What we want to achieve is being able to anchor this view so it can't be dragged around the app and can only be scrolled vertically.
In the integration code we have access to a UIView for the offerwall and the ViewController of the main app.
The offerwall is provided as a library so I don't have access to any of its code and can only deal with the UIView returned and the UIViewController I add it to. Other apps have managed to implement the view without horizontal scrolling
We are looking for code to apply to either the UIView or ViewController to prevent this.
Thanks
The offerwall view probably contains a UIScrollView that holds the actual content. You could try looping through all subviews and turn off scrolling on the first scroll view it finds:
for (UIView *view in offerwall.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView *scrollView = (UIScrollView*)view;
scrollView.scrollEnabled = NO;
return;
}
}
This is definitely hacky, but if you don't have access to anything else from their code it might be your only option.
In the end the solution was quite simple. Turns out the offerwall was a UIWebView and in testing mode the offerwall page was rendering some elements that were overflowing the page hence the horizontal scrolling. In production mode the problem goes away

iOS 6 UIGestures (Swipe) stops working with QLPreviewController

In iOS 6 beta 4 and iOS 5.1.1 I have had left/right swipes allowing users to swipe between different QLPreviewControllers, hosted in a UIViewController.
In the released version of iOS 6 the swipes are now completely ignored.
Attempted to put a UIView as a subview of the preview controller in an attempt to get the view hosting the preview controller to intercept the swipes before the preview controller has a chance to swallow them, but these are never triggered.
Any one seen this or know of a work around.
Thanks,
I had the same problem but with UITapGestureRecognizer not working on QLPreviewController. In iOS 6 that thing is like a black hole for UIGestureRecognizer objects...nothing makes it out of there!
However I did find a workaround. I am subclassing QLPreviewController, so in my subclass I abused the (relatively) new viewWillLayoutSubviews method and added the following snippet:
UIView *overlay = [[UIView alloc] initWithFrame:self.view.frame];
overlay.backgroundColor = [UIColor whiteColor];
overlay.alpha = .002f;
for (UIView *v in self.view.subviews)
{
[v addSubview:overlay];
}
[overlay release];
It may be overkill, but I basically went into the all of the quick look subviews and added a view to them that WOULD accept the gesture. I went with .002 alpha because making it lower would cause the gestures to be ignored again.
I have also found that using the same code, UIGestureRecognizers have stopped working under iOS 6. But it is not that totally broken. Apple Development Sample project "SimpleGestureRecognizers" still functions. After comparing the code, I found that explicitly "addGestureRecognizer" resolved the problem (besides all the other steps you used to do under IB). Assuming your one of your IBOutlets names leftSwiftRecognizer, you could do:
- (void)viewDidLoad
{
[super viewDidLoad];
....
// swipe recognizer
[self.view addGestureRecognizer:self.leftSwiftRecognizer];
}
Your attempted solution was close, but probably backwards from what you should have done. Instead of adding another view as a subview of the preview controller, add the preview controller as a subview of the UIView.
Subview the preview controller inside a standard UIView. Then, reassign your gestures to the UIView's gestureRecognizers collection, removing them from the QLPreviewController's collection.
Not sure why this changed, but I had the same issue with my app, except for me it was the UITableView that wasn't scrolling anymore.

Resources