Frage

Ich habe einen nackten Knochen iPhone App mit einer UIWebView (Scales Seite zu Fit = YES, ShouldAutorotateToInterfaceOrientation = YES) und geladen, um eine Webseite, z.B. https://stackoverflow.com/

Drehen der Vorrichtung zeigt, dass UIWebView wird automatisch der Größe verändert die Breite passen. Gut.

Falscher : Zoom in der Seite und verkleinert. Nun Drehen der Vorrichtung zeigt UIWebView in einer seltsamen Breite in einem von der Ausrichtung (wenn u im Quer vergrößern, das Porträt Breite ist seltsam, vice versa). Dieses Verhalten wird nur festgelegt, wenn Sie zu einer anderen Seite navigieren.

Richtig : Legen Sie die gleiche URL in Mobile Safari. Rotierende Arbeiten & die Breite passt, unabhängig von der Zoom Übung.

Ist das ein UIWebView Fehler (wahrscheinlich nicht)? Oder gibt es etwas, dass Bedürfnisse, um die Dinge „einfach funktionieren“ wie in Mobile Safari zu tun?

War es hilfreich?

Lösung

fand ich etwas, das für mich gearbeitet. Das Problem ist, dass, wenn UIWebView ändert seine Ausrichtung Webinhalte mit Ansichtsfenstern sind zoommed zu passen. Aber zoomscale Parameter Scroll subview nicht korrekt aktualisiert (noch aktualisiert minimumZoomScale noch maximumZoomScale

Dann müssen wir es manuell willRotateToInterfaceOrientation tun:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    CGFloat ratioAspect = webview.bounds.size.width/webview.bounds.size.height;
    switch (toInterfaceOrientation) {
        case UIInterfaceOrientationPortraitUpsideDown:
        case UIInterfaceOrientationPortrait:
            // Going to Portrait mode
            for (UIScrollView *scroll in [webview subviews]) { //we get the scrollview 
                // Make sure it really is a scroll view and reset the zoom scale.
                if ([scroll respondsToSelector:@selector(setZoomScale:)]){
                    scroll.minimumZoomScale = scroll.minimumZoomScale/ratioAspect;
                    scroll.maximumZoomScale = scroll.maximumZoomScale/ratioAspect;
                    [scroll setZoomScale:(scroll.zoomScale/ratioAspect) animated:YES];
                }
            }
            break;
        default:
            // Going to Landscape mode
            for (UIScrollView *scroll in [webview subviews]) { //we get the scrollview 
                // Make sure it really is a scroll view and reset the zoom scale.
                if ([scroll respondsToSelector:@selector(setZoomScale:)]){
                    scroll.minimumZoomScale = scroll.minimumZoomScale *ratioAspect;
                    scroll.maximumZoomScale = scroll.maximumZoomScale *ratioAspect;
                    [scroll setZoomScale:(scroll.zoomScale*ratioAspect) animated:YES];
                }
            }
            break;
    }
}

Hope, das hilft!

Andere Tipps

Ich habe die Lösung von M Penades versucht, und dies scheint auch für mich zu arbeiten.

Das einzige Problem, das ich erlebt habe, ist, dass, wenn diese auf einem 3Gs läuft die Rotation ist leider nicht sehr glatt.

Ich bin jetzt also einen anderen Ansatz:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {

[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

CGFloat scale = browserWebView.contentScaleFactor;
NSString *javaStuff = [NSString stringWithFormat:@"document.body.style.zoom = %f;", scale];
[browserWebView stringByEvaluatingJavaScriptFromString:javaStuff];

}

Die besten Grüße, Ralph

- (UIScrollView *)findScrollViewInsideView:(UIView *)view
{
    for(UIView *subview in view.subviews){
        if([subview isKindOfClass:[UIScrollView class]]){
            return (UIScrollView *)subview;
        }

        UIScrollView *foundScrollView = [self findScrollViewInsideView:subview];
        if (foundScrollView){
            return foundScrollView;
        }
    }

    return nil;
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    switch (self.interfaceOrientation){
        case UIInterfaceOrientationLandscapeLeft:
        case UIInterfaceOrientationLandscapeRight:
        {
            UIScrollView *webViewScrollView = ([self.webView respondsToSelector:@selector(scrollView)])
                ? self.webView.scrollView
                : [self findScrollViewInsideView:self.webView];

            [webViewScrollView setZoomScale:1.01f animated:YES];
        }
            break;

        default:
            break;
    }
}

versuchen, diesen Code, es unwesentlich ändert Zoomstufe (1,01) UIWebView Erhöhung Inhaltsgröße im Querformat

zu ermöglichen

findScrollViewInsideView: Methode zur Unterstützung hinzugefügt ios4

ich dieses Posting, weil ich habe auch das gleiche Problem konfrontiert und hier bin ich nach dem M Penades Approach.M Penades ‚s Antwort Woks nur gut für Fall, wenn Benutzer Skew nicht (Prise) die Webview dann drehen Sie das Gerät, und wiederholen Sie dieser Prozess .then Inhalt Größe von UIWebview bekommt allmählich reduzieren. so dass die Frage kam in M Penades Antwort war. so habe ich festgelegt, dass Problem zu und mein Code ist als unten.

1) für diese Ich habe die Pinch-Geste so, dass, wenn Benutzer Skew Die UIWebview die skalierten Größe UIWebview überprüfen konnte. // One Diese Bitte importieren Sie die UIGestureRecognizerDelegate Protokoll in 'H-Datei'

     //call below method in ViewDidLoad Method for setting the Pinch gesture 

- (void)setPinchgesture
{
     UIPinchGestureRecognizer * pinchgesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(didPinchWebView:)];

    [pinchgesture setDelegate:self];

    [htmlWebView addGestureRecognizer:pinchgesture];
    [pinchgesture release];
   // here htmlWebView is WebView user zoomingIn/Out 

}
   //Allow The allow simultaneous recognition

  - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer   *)otherGestureRecognizer
  {
     return YES;
  }

Rückkehr JA ist garantiert gleichzeitige Erkennung zu ermöglichen. Zurückkehren NO garantiert nicht die gleichzeitige Anerkennung, wie die anderen Geste des Delegierten zu verhindern, kann das Rück YES

 -(void)didPinchWebView:(UIPinchGestureRecognizer*)gestsure
   {
   //check if the Scaled Fator is same is normal scaling factor the allow set Flag True.
    if(gestsure.scale<=1.0)
    {
    isPinchOut = TRUE;

    }
    else// otherwise Set false
    {
    isPinchOut = FALSE;
   }
  NSLog(@"Hello Pinch %f",gestsure.scale);
}

Wenn Benutzer Hase Pinch In / Out Die Web-Ansicht in diesem Fall nur Set, das Zooming-Faktor. So dass WebView Seinen Content anpassen als Oreintaion geändert.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation   duration:(NSTimeInterval)duration {

   //Allow the Execution of below code when user has Skewed the UIWebView and Adjust the Content Size of UiwebView.

  if(isPinchOut){
  CGFloat ratioAspect = htmlWebView.bounds.size.width/htmlWebView.bounds.size.height;
  switch (toInterfaceOrientation) {
    case UIInterfaceOrientationPortraitUpsideDown:
    case UIInterfaceOrientationPortrait:
        // Going to Portrait mode
        for (UIScrollView *scroll in [htmlWebView subviews]) { //we get the scrollview
            // Make sure it really is a scroll view and reset the zoom scale.
            if ([scroll respondsToSelector:@selector(setZoomScale:)]){
                scroll.minimumZoomScale = scroll.minimumZoomScale/ratioAspect;
                scroll.maximumZoomScale = scroll.maximumZoomScale/ratioAspect;
                [scroll setZoomScale:(scroll.zoomScale/ratioAspect) animated:YES];
            }
        }
        break;

    default:
        // Going to Landscape mode
        for (UIScrollView *scroll in [htmlWebView subviews]) { //we get the scrollview
            // Make sure it really is a scroll view and reset the zoom scale.
            if ([scroll respondsToSelector:@selector(setZoomScale:)]){
                scroll.minimumZoomScale = scroll.minimumZoomScale *ratioAspect;
                scroll.maximumZoomScale = scroll.maximumZoomScale *ratioAspect;
                [scroll setZoomScale:(scroll.zoomScale*ratioAspect) animated:YES];
            }
        }
        break;
     }
  }

}

Das funktioniert perfekt für selbst Benutzer Skew die UIWebView.

habe ich eine Lösung für dieses Problem, aber ich muß sagen, ich bin kein großer Fan von ihm. Es funktioniert großartig, aber die Lösung tatsächlich bewirkt, dass ein anderes Problem. Ich habe ein Update für die zweitrangig, aber es dauert ein wenig Mühe.

Denken Sie daran, dass seit OS3.2 oder iOS4 (nicht sicher, welche) UIWebView direkte subview ist jetzt UIScrollView statt UIScroller, so dass wir viel mehr damit machen kann. Da auch Subviews einer Ansicht Zugriff ist keine private Handlung, weder mit einem Subview, die als dokumentierte Ansicht gegossen ist, dass wir viel mit dem UIWebView tun können, ohne die Regeln zu brechen.

Zunächst müssen wir die UIScrollView vom UIWebview bekommen:

UIScrollView *sview = [[webView subviews] objectAtIndex:0];

Jetzt müssen wir die Vertreter dieses Scroll ändern, damit wir Scroll delegieren Anrufe außer Kraft setzen können (die tatsächlich die Ursache eines sekundären Fehler als Folge dieser Lösung sein kann, die ich in einem Moment teilen werden):

sview.delegate = self;

Nun, wenn Sie es an dieser Stelle versuchen, zoomt gebrochen. Wir brauchen eine UIScrollViewDelegate Methode zu implementieren, es zu beheben. hinzufügen:

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    UIView *webBrowserView = [[scrollView subviews] objectAtIndex:10];
    return webBrowserView;
}

webBrowserView ist eigentlich ein UIWebBrowserView, aber das ist nicht eine dokumentierte Klasse, so dass wir es einfach als UIView behandeln werden.

Jetzt ist Ihre Anwendung ausführen, zoomen und dann die Webseite verkleinern. Drehen, und es sollte richtig angezeigt werden.

Dies verursacht einen ziemlich großen Fehler, die vielleicht schlechter als das Original ist.

Wenn Sie zoomen und drehen, verlieren Sie Fähigkeit Scrollen, aber Ihre Ansicht wird noch vergrößert werden. Hier ist das Update, das Ganze zu beenden.

Zuerst müssen wir den Überblick über ein paar Zahlen halten und haben eine Fahne definiert:

Ich habe diese definiert in meiner h-Datei:

BOOL updateZoomData;
float zoomData; //this holds the scale at which we are zoomed in, scrollView.zoomScale
CGPoint zoomOffset; //this holds the scrollView.contentOffset
CGSize zoomContentSize; //this holds the scrollView.contentSize

Sie denken, Sie können nur diese Zahlen von UIScrollView greifen kann, aber wenn man sie braucht, werden sie geändert haben, so müssen wir sie an anderer Stelle gespeichert.

Wir brauchen eine andere Delegatmethode verwenden:

- (void)scrollViewDidZoom:(UIScrollView *)scrollView{
    if(updateZoomData){
        zoomData = scrollView.zoomScale;
        zoomOffset = scrollView.contentOffset;
        zoomContentSize = scrollView.contentSize;
    }
}

Jetzt wird es in ein Chaos ich fühle.

Wir brauchen Rotation zu verfolgen, so dass Sie diese zu Ihrem viewDidLoad, Loadview hinzuzufügen brauchen, oder was auch immer Methode verwenden Sie Benachrichtigungen registrieren:

[[NSNotificationCenter defaultCenter] addObserver:self 
            selector:@selector(webViewOrientationChanged:) 
            name:UIDeviceOrientationDidChangeNotification 
            object:nil];

und erstellen Sie diese Methode:

- (void)webViewOrientationChanged:(NSNotification *)notification{
    updateZoomData = NO;
    [self performSelector:@selector(adjustWithZoomData) withObject:nil afterDelay:0.0];
}

So, jetzt jederzeit drehen Sie webViewOrientationChange aufgerufen. Der Grund perform für 0,0 Sekunden verzögert wird, weil wir adjustWithZoomData auf der nächsten Runloop anrufen möchten. Wenn Sie es direkt anrufen, wird die adjustWithZoomData für die vorherige Ausrichtung anzupassen.

Hier ist die adjustWithZoomData Methode:

- (void)adjustWithZoomData{
    UIScrollView *sview = [[webView subviews] objectAtIndex:0];
    [sview setZoomScale:zoomData animated:YES];
    [sview setContentOffset:zoomOffset animated:YES]; 
    [sview setContentSize:zoomContentSize];
    updateZoomData = YES;
}

Das ist es! Nun, wenn Sie drehen wird es halten Zoom und etwa die Offset richtig halten. Wenn jemand will, die Mathematik tun, wie die genauen richtigen dann geht sie versetzt zu bekommen!

Ich wurde in diese suchen mich und fand heraus, einige weitere Informationen:

Probleme beim Zoom Ändern:

  1. Safari nicht neu streicht oft nicht richtig (wenn überhaupt), obwohl Zoomstufe geändert.
  2. Ändern der Breite Kräfte ein Neuzeichnen.
  3. Sie würden denken, width = device-Breite in der Landschaft verwenden 1024 würde, aber es scheint, 768 zu verwenden (screen.width geschieht auch).

z. wenn aktuelle Breite ist 1024 und Sie mögen 1-1,5 in der Landschaft vergrößern kann man:

  • Änderung Kombination von Breite und Zoom z.B. Breite bis 2048 und Zoom auf 0,75
  • Änderungsbreite bis 1023 (hässlich Aliasing?)
  • Änderungsbreite sagen 1023, dann nächste Zeile zurück auf 1024 (Doppel repaint, aber zumindest Fenster neu gestrichen).

So anscheinend habe ich nicht die Lösung von M Penades am Ende benutzen (und vergessen habe, diesen Beitrag zu aktualisieren! Sorry).

Was ich tat, war das gesamte Dokument, um die Größe (und meine font-size ändern sich die Dinge im Verhältnis zu halten). Das scheinbar das Problem behoben.

Aber meine UIWebView ist nur für meine eigenen HTML & CSS aus dem iOS-Dateisystem geladen -. Wenn Sie bauen einen Allzweck-Web-Browser, dieser Trick funktioniert möglicherweise nicht so gut

ViewController.m

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    switch (toInterfaceOrientation) {
        case UIInterfaceOrientationPortraitUpsideDown:
        case UIInterfaceOrientationPortrait:
            if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)) {
                [webview stringByEvaluatingJavaScriptFromString:@"document.body.className = 'ppad'"];
            } else {
                [webview stringByEvaluatingJavaScriptFromString:@"document.body.className = 'pphone'"];
            }
            break;
        default:
            if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)) {
                [webview stringByEvaluatingJavaScriptFromString:@"document.body.className = 'lpad'"];
            } else {
                [webview stringByEvaluatingJavaScriptFromString:@"document.body.className = 'lphone'"];
            }
            break;
    }
}

Und app.css

html>body.pphone { font-size:12px; width: 980px; }
html>body.lphone { font-size:18px; width: 1470px; }
html>body.ppad { font-size:12px; width: 768px; }
html>body.lpad { font-size:15.99999996px; width: 1024px; }

Gist unter https://gist.github.com/d6589584944685909ae5

Bei der Drehung, versuchen Sie die Scroll zoomScale auf 0 setzen. Sehen Sie meine vollständige Antwort hier: UIWebView Inhalt nicht eingestellt In dem neuen Rahmen nach der Drehung

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top