Cannot scroll in UIWebView in iOS - objective-c

I created a webview programmatically and I am unable to enable scrolling in this view.
How do I enable scrolling?
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,40, 325, 1000)];
webView.contentMode = UIViewContentModeScaleAspectFit;
[webView setBackgroundColor:[UIColor clearColor]];
[webView loadHTMLString:html baseURL:nil];
[self.view insertSubview:webView atIndex:0];
Thanks In Advance !

To enable scrolling,
webview.scrollView.scrollEnabled = TRUE;
and instead of writing this,
webView.contentMode = UIViewContentModeScaleAspectFit;
write this,
webview.scalesPageToFit = TRUE;

These are the possible solutions.
i) You webview may be large in size than you expected or your content is lesser than the webview size.
2) Implement following method.
func webViewDidFinishLoad(webView: UIWebView)
{
appDelegate.hideLoadingView()
let res: NSString = webView.stringByEvaluatingJavaScriptFromString("document.body.offsetHeight;")!
let h: CGFloat = CGFloat(res.integerValue)
agreementContentView.scrollView.contentSize = CGSizeMake(webView.frame.size.width, h + 50); // Offset if required
}

Removing from Interface Builder and adding via code did for me. For some reason in IB it wasn't scrolling.
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 64, 320, 50)];
[self.view addSubview: webView];

Related

How to correctly add WKWebView to accessibilityElements in an AccessibilityContainer?

I have a custom configured Accessibility tree using AccessibilityContainer and AccessibilityElements. Now I want to add a WKWebView under one of the AccessibilityContainers as an AccessibilityElements.
Everything works except that if I want to select an accessibility element directly (moving finger around the web view to find elements).
I replaced the WKWebView with deprecated UIWebView and it worked flawlessly.
And If I don't have the custom configured tree, WKWebView's accessibility works perfectly too.
I have created a sample code to reproduce the issue, what I am doing in this code might not make sense in a real application but it replicates the set up I have in my project.
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 100)];
label.backgroundColor = [UIColor yellowColor];
label.textColor = [UIColor blueColor];
label.text = #"Here is some text";
CGRect webViewRect = CGRectMake(0, 100, self.view.bounds.size.width, self.view.bounds.size.height-100);
WKWebView *webview = [[WKWebView alloc] initWithFrame:webViewRect];
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"https://google.com"]]];
webview.accessibilityFrame = webViewRect;
[self.view addSubview:label];
[self.view addSubview:webview];
self.view.accessibilityElements = #[label, webview];
// Do any additional setup after loading the view, typically from a nib.
}
I would expect the elements in the WKWebView selectable by the Accessibility Inspector but they aren't in this case.

sendSubviewToBack on UITableView not working properly in iOS 11

I have an UITableViewController to which I successfully applied in the past a gradient background, by sending the newly added subview to back:
//performed on viewDidLoad
UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1.5*280, 1.5*SCREEN_HEIGHT)];
bgView.backgroundColor = [UIColor yellowColor];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = bgView.bounds;
gradient.startPoint = CGPointMake(0, 0);
gradient.endPoint = CGPointMake(1, 1);
UIColor *topColor = UIColorFromRGB(0x229f80);
UIColor *bottomColor = UIColorFromRGB(0x621ad9);
gradient.colors = [NSArray arrayWithObjects:(id)[topColor CGColor], (id)[bottomColor CGColor], nil];
[bgView.layer insertSublayer:gradient atIndex:0];
[self.view addSubview:bgView];
[self.view sendSubviewToBack:bgView];
bgView = nil;
However, this no longer works in iOS 11 and the bgView is actually placed on top of all the cells.
Anyone knows how I can fix this?
Or maybe I was doing it wrong all the time?
If your cells are transparent then you can try self.tableView.backgroundView = bgView;
If you don't need the background view to be scrolling together with the table view, you can use
self.tableView.backgroundView = bgView;
If you need the background view to be scrolling, change layer's zPosition to a negative value to make it work in iOS 11:
[self.view insertSubview:bgView atIndex:0];
bgView.userInteractionEnabled = NO;
bgView.layer.zPosition = -1;
Another way to fix it is to call [self.view sendSubviewToBack:bgView]; in tableView:willDisplayCell:forRowAtIndexPath:
It works for not transparent cells also.
it appears that addSubview(UIView) sendSubview(toBack: UIView) no longer works for UITableViewControllers in iOS11. So I swap to this:
// in ViewDidLoad
// set the backgroundImage
let backgroundImage = UIImageView(frame: self.view.bounds)
backgroundImage.image = UIImage(named: "background.png")
// self.view.addSubview(backgroundImage) // NO LONGER WORKS
// self.view.sendSubview(toBack: backgroundImage) // NO LONGER WORKS
self.tableView.backgroundView = backgroundImage

How do I add a subView to a webView in OS X so It will scroll

This should work but doesn't. Something similar will work in iOS though.
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
NSView<WebDocumentView>* doc = [[[self.webView mainFrame] frameView] documentView];
TestView* testView = [[TestView alloc]init];
[testView setFrame:CGRectMake(200, 400, 100, 50)];
NSScrollView* sv = [doc enclosingScrollView];
[sv addSubview:testView];
[self.webView setNeedsDisplay:YES];
}
testView appears but will not scroll along with doc. Adding it to sender produces the same results. Adding testView to doc produces no visible effect.
If no one knows another way to do it, I should be able to do it with live scrolling notifications .
Thanks
I have done as you suggest. The demo app is at: https://dl.dropboxusercontent.com/u/108679476/webDemo.zip
I have experimented with setNeedsDisplay for webView, doc, and sv.
The AddToScrollView button works but will not scroll or magnify.
The AddToDoc buttons does not work under any conditions that I have tried.
Is it possible that the scrollView is ignoring setNeedsDisplay because it doesn't know that doc has been changed?
Thanks
It wasn't moving because you were adding it to NSClipView. As mentioned in comment it should be added into documentView. Once I did it I faced issue that I wasn't able to see the view. So I started tool called "Interface Inspector" and verified the view. It was there, correctly moving but not being drawn. So I changed your view to be layer backed and it started to work.
-(IBAction)addToScrollView:(id)sender
{
NSView<WebDocumentView>* doc = [[[self.webView mainFrame] frameView] documentView];
TestView* testView = [[TestView alloc]init];
[testView setFrame:CGRectMake(200, self.currentSVYCoordinate, 100, 50)];
testView.wantsLayer = YES;
CALayer *layer = [[CALayer alloc] init];
layer.backgroundColor = [[NSColor redColor] CGColor];
testView.layer = layer;
self.currentSVYCoordinate = self.currentSVYCoordinate + 200;
NSScrollView* sv = [doc enclosingScrollView];
NSView *documentView = [sv documentView];
[documentView addSubview:testView];
[sv setNeedsDisplay:YES];
}
This appears to be the correct way. It scrolls and responds to mouseDown, but it does not magnify:
-(IBAction)addToScrollView:(id)sender
{
NSView<WebDocumentView>* doc = [[[self.webView mainFrame] frameView] documentView];
TestView* testView = [[TestView alloc]init];
[testView setFrame:CGRectMake(200, self.currentSVYCoordinate, 100, 50)];
self.currentSVYCoordinate = self.currentSVYCoordinate + 200;
//Use testview's drawRect to add a color
NSScrollView* sv = [doc enclosingScrollView];
[sv.contentView addSubview:testView];
[self.webView setNeedsDisplay:YES];
}

add UIWebView programmatically to UIImageView

I would like to be able to add zoom functionality to UIImage and believe the best way is to embed within UIWebview. Would someone be able to help me achieve this?
- (void)viewDidLoad
{
[super viewDidLoad];
// image
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 70, IMGSIZE.width, IMGSIZE.height)];
[self.imageView setClipsToBounds:YES];
self.imageView.layer.borderColor = kITBarTint.CGColor;
self.imageView.layer.borderWidth = 1.0;
self.imageView.layer.cornerRadius = 15.0;
self.imageView.layer.shadowColor = [UIColor blackColor].CGColor;
self.imageView.layer.shadowOffset = CGSizeMake(5, 5);
self.imageView.layer.shadowRadius = 10;
[self.controller.view addSubview:self.imageView];
// activity indicator
CGRect frame = CGRectMake(roundf(IMGSIZE.width / 2) + self.imageView.frame.origin.x, roundf(IMGSIZE.height /2) + self.imageView.frame.origin.y, 0, 0);
_activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[_activityIndicator setFrame:frame];
[_activityIndicator startAnimating];
[self.controller.view addSubview:_activityIndicator];
}
Try adding this to your viewDidLoad method,
scrollView.minimumZoomScale = 0.4;
scrollView.maximumZoomScale = 4.0;
scrollView.delegate = self;
[scrollView setZoomScale:scroll.minimumZoomScale];
Hope this helps!!
And try using a UIScrollView
You don't need to Use a UIImageview additionally.
For Local files use file:// as url. you can get a path of a file width:
NSString *path = [[NSBundle mainBundle] pathForResource:#"myimage" ofType:#"jpg"];
For the Webview simple create a Html Code as String.
[webView loadHTMLString: [NSString stringWithFormat:#"<html><head></head><body><img src=\"file://%#\"></body></html>",path] baseURL:nil];
Inside the HTML String you can also use CSS for sizing or positioning!

Content change when UIWebView load inside ScrollView

I want to make something like Pulse news when user read the selected news.
When image is not loaded, the space for the image is not yet specified. After the image is loaded, the size of the content also change (the text will be pushed down to make space for the image).
How can i do that?
What i do now is using scroll view, with uiwebview inside it.
- (void)loadView
{
self.view = [[UIView alloc] initWithFrame:CGRectZero];
UIView *thisView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
contentTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, 292, 82)];
contentThumbnailWebView = [[UIWebView alloc] initWithFrame:CGRectMake(10, CGRectGetMaxY(contentTitleLabel.frame), 292, 0)];
contentDateLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, CGRectGetMaxY(contentThumbnailWebView.frame), 292, 23)];
playVideoButton = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetMaxX(contentThumbnailWebView.frame)/2, CGRectGetMaxY(contentThumbnailWebView.frame)/2, 72, 37)];
[playVideoButton setTitle:#"Play" forState:UIControlStateNormal];
playVideoButton.hidden = YES;
contentSummaryLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, CGRectGetMaxY(contentDateLabel.frame), 292, 20)];
contentScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
contentScrollView.backgroundColor = [UIColor whiteColor];
[thisView addSubview:contentScrollView];
[contentScrollView addSubview:contentDateLabel];
[contentScrollView addSubview:contentTitleLabel];
[contentScrollView addSubview:contentThumbnailWebView];
[contentScrollView addSubview:playVideoButton];
[contentScrollView addSubview:contentSummaryLabel];
//[self.view addSubview:thisView];
self.view = thisView;
contentThumbnailWebView.delegate = self;
}
I've read several topics about this but i still cannot solve it.
- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
CGRect frame = aWebView.frame;
frame.size.height = 1;
aWebView.frame = frame;
CGSize fittingSize = [aWebView sizeThatFits:CGSizeZero];
fittingSize.width = aWebView.frame.size.width;
frame.size = fittingSize;
aWebView.frame = frame;
NSLog(#"size: %f, %f", fittingSize.width, fittingSize.height);
[contentDateLabel setFrame:CGRectMake(10, CGRectGetMaxY(aWebView.frame), 292, 23)];
playVideoButton = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetMaxX(aWebView.frame)/2, CGRectGetMaxY(aWebView.frame)/2, 72, 37)];
[contentSummaryLabel setFrame:CGRectMake(10, CGRectGetMaxY(contentDateLabel.frame), 292, contentSummaryLabel.frame.size.height )];
contentScrollView.contentSize = CGSizeMake(contentScrollView.frame.size.width, CGRectGetMaxX(contentSummaryLabel.frame));
}
I load jpg image link on it. The image is loaded but the height is not resize correctly. and i also cannot scroll again the scrollView when the webview is loaded.
Below is when i call the image to be loaded
- (void) setImageAsThumbnail:(NSString *)imagehumbnailLink
{
NSURL *imageURL = [NSURL URLWithString:imageThumbnailLink];
NSString *cssString = #"<style type='text/css'>img {width: 292px; height: auto;}</style>";
NSString *myHTMLContent = #"<html><head></head><body><img src='%#'></body></html>";
NSString *htmlString = [NSString stringWithFormat:#"%#%#",cssString,myHTMLContent];
NSString *imageHTML = [[NSString alloc] initWithFormat:htmlString, imageURL];
contentThumbnailWebView.scalesPageToFit = YES;
[contentThumbnailWebView loadHTMLString:imageHTML baseURL:nil];
}
Thank you!
I frequently use UIWebView inside UIScrollView, and because loading HTML is done asynchronously you have to resize the web view and the content size of the scroll view when finished.
[webView sizeThatFits:CGSizeZero]
does not work for me either. Instead, in your webViewDidFinishLoad:(UIWebView*)webView you can measure the size of the HTML document by executing a piece of Javascript:
NSString *js = #"document.getElementById('container').offsetHeight;";
NSString *heightString = [webView stringByEvaluatingJavaScriptFromString:js];
int height = [heightString intValue]; // HTML document height in pixels
In this example, you have to assign the ID 'container' to the top-level element in your HTML (make sure there are no margins around it). This approach works very well for me.