Venk
Venk

Reputation: 5955

UIWebView's content height returns wrong value while using mathjax

I am using mathjax for displaying the mathematical expressions on UIWebView. So i want to change the UIWebView height dynamically. For that , i have used

CGFloat newHeight = [[self.questionWebView stringByEvaluatingJavaScriptFromString:@"document.documentElement.scrollHeight;"] floatValue];

in webViewDidFinishLoad: delegate method.

Here my problem is if i am using normal expression the UIWebView height returns correct value as like in the following image,

enter image description here

if i enter the expression which contains /,(,) it will give the wrong height as like in the following image

enter image description here

 NSString *html = [NSString stringWithFormat:@"<html><head><title>Untitled</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><script type=\"text/x-mathjax-config\">MathJax.Hub.Config({extensions: [\"tex2jax.js\"],jax: [\"input/TeX\",\"output/HTML-CSS\"],tex2jax: {inlineMath: [[\"$\",\"$\"],[\"\\(\",\"\\)\"]]}});</script><script type=\"text/javascript\" src=\"../MathJax.js?config=AM_HTMLorMML-full\"></script></head><style>.Question {font-family:'Times New Roman',arial;font-weight:normal;font-size:12px;color:#323232;}</style><body><table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"Question\" align=\"left\" width=\"260\" height=\"40\"><tr><td> `x + 3 = 2` </td></tr></div></body></html>"];

[self writeStringToFile:tempDir fileName:@"test1.html" pathName:filePath content:html];

NSURLRequest* req = [[NSURLRequest alloc] initWithURL:url];

[self.myWebView loadRequest:req]; 

In writeStringToFile: method,

-(void)writeStringToFile:(NSString *)dir fileName:(NSString *)strFileName pathName:(NSString *)strPath content:(NSString *)strContent{

    NSString *path = [dir stringByAppendingPathComponent:strFileName];
    NSString *foo0 = @"<html><head><meta name='viewport' content='initial-scale=1.0;maximum-scale=100.0;user-scalable=1'/>"
    "<script type='text/javascript' src='";
    NSString *foo1 = @"?config=AM_HTMLorMML-full'></script>"
    "</head>"
    "<body>";
    NSString *foo2 = @"</body></html>";
    NSString *fooFinal = [NSString stringWithFormat:@"%@%@%@%@%@",foo0,strPath,foo1,strContent,foo2];

    [fooFinal writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
}

How to get the exact height?

Thanks in advance!

Upvotes: 0

Views: 1168

Answers (3)

Venk
Venk

Reputation: 5955

Finally after a long research, i have found the solution with the help of @Davide Cervone answer and the sample https://github.com/dannywartnaby/KPWebViewInterceptor,

Just added the objective-c method call in .html file

<script type="text/x-mathjax-config">
  MathJax.Hub.Queue(function myFunction() {
                          objc_msgsend('myFunction');
                          });
</script>

in.js file

var KP_INTERCEPTOR_INVOCATION_COMMAND = "invoke"
var KP_INTERCEPTOR_SEPERATOR = ":"
function objc_msgsend() {
    var selector = arguments[0];
    var invocation = selector;

    if ( arguments.length > 1 ) {

        for( var i = 1; i < arguments.length; i++ ) {
            invocation = invocation + KP_INTERCEPTOR_SEPERATOR + arguments[i];
        }
    }

    window.location = KP_INTERCEPTOR_INVOCATION_COMMAND + KP_INTERCEPTOR_SEPERATOR + invocation;
}

in webView Delegate

- (BOOL)webView:(UIWebView *)source shouldStartLoadWithRequest:(NSURLRequest *)request  navigationType:(UIWebViewNavigationType)navigationType {

    if([[[request URL] absoluteString] hasPrefix:@"invoke"]) {
        [self myFunction];
        return NO;
    }
    return YES;
}

Upvotes: 2

Davide Cervone
Davide Cervone

Reputation: 12290

The problem is that MathJax takes some time to perform its actions, and you are getting the new height before MathJax has typeset the mathematics (i.e., when it is still just a line of text). You will have to synchronize your new height with the actions of MathJax. I don't know anything about UIWebView programming, but you can have MathJax tell you about when it is finished with its typesetting by including

<script type="text/x-mathjax-config">
  MathJax.Hub.Queue(function () {alert("done")});
</script>

in the HTML somewhere before the script that loads MathJax.js itself. Of course, you would need to replace alert("done") with whatever action is required to communicate back to the code running your UIWebView (that's the part I don't know). Can you detect events or changes to values inside the UIWebView from outside? If so, that is what you would do in the function that is queued, and your outside code would need to wait for that action before it changed the height.

Upvotes: 3

Valent Richie
Valent Richie

Reputation: 5226

I usually use the height of the scrollView contentSize of the web view after it is finished loading:

- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
    CGFloat newHeight = aWebView.scrollView.contentSize.height;
}

Try that and see if it returns the correct height for you.

Upvotes: -1

Related Questions