当方向改变时,UIWebView无法正确调整大小?

时间:2011-05-15 10:46:09

标签: objective-c uiwebview resize orientation

我在viewcontroller的视图中添加了webview,titleLabel和coverflowView作为其子视图,我希望它在方向更改时更改大小。我已在此方法中更改了webview的框架:

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

如果我以纵向方向启动应用程序,当将iPad从orientationLandscape旋转到orientationPortrait或从orientationPortrait旋转到orientationLandscape时,其内容会调整大小,但是当我以横向方向启动应用程序时,它的内容不会调整大小。 。但NSLog显示框架已更改。至于titleLabel和coverflowView,它们可以正确调整大小。我怀疑是不是因为css?我根据webview的高度和宽度使用css控制内容的样式。有人能帮我找到原因吗?代码如下:

- (void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation duration: (NSTimeInterval)duration {
double i = 0;
NSInteger  width=self.view.frame.size.width;
NSInteger  height=self.view.frame.size.height;
NSLog(@"view :%@",[self.view description]);
switch (toInterfaceOrientation){
    case UIInterfaceOrientationPortrait:
    {    
        NSLog(@"rotate to Portrait");
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
            self.docView.frame=CGRectMake(0, 50, width+20, height-70);
            self.toolbar.frame=CGRectMake(0, 0,height , 50);
            for (UIView * view in [toolbar subviews]) {
                if ([view isKindOfClass:[UIButton class]] && view.tag==kBackButtonTag){
                    view.frame=CGRectMake(width-60, 6, 50, 36);

                }else if([view isKindOfClass:[UIButton class]] && view.tag==kReloadButtonTag){
                    view.frame=CGRectMake(width-160, 6, 80,36 );
                }
            }
            [coverflow setFrame:CGRectMake(0, 0 , width+20, height/2-50)];
            [titleLabel setFrame:CGRectMake(width/2-40,height/2-100, 100, 20)];
            if ([[[UIDevice currentDevice]model]isEqualToString:@"iPad"]) {
                self.viewer.frame=CGRectMake(0, 0, 768, 1004);
            }else{
                self.viewer.frame=CGRectMake(0, 0, 320, 480);
            }
        }
        i=0;
    }break;
    case UIInterfaceOrientationPortraitUpsideDown:
    {
        NSLog(@"rotate to PortraitUpsideDown");
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
            self.docView.frame=CGRectMake(0, 50, width+20, height-70);
            self.toolbar.frame=CGRectMake(0, 0,height , 50);
            for (UIView * view in [toolbar subviews]) {
                if ([view isKindOfClass:[UIButton class]] && view.tag==kBackButtonTag)  {
                    view.frame=CGRectMake(width-60, 6, 50, 36);

                }else if([view isKindOfClass:[UIButton class]] && view.tag==kReloadButtonTag){
                    view.frame=CGRectMake(width-160, 6, 80,36 );
                }
            }

            [coverflow setFrame:CGRectMake(0, 0 , width+20, height/2-50)];
            [titleLabel setFrame:CGRectMake(width/2-40,height/2-100, 100, 20)];
            if ([[[UIDevice currentDevice]model]isEqualToString:@"iPad"]) {
                self.viewer.frame=CGRectMake(0, 0, 768, 1004);
            }else{
                self.viewer.frame=CGRectMake(0, 0, 320, 480);
            }

        }

        i=180;
    }   break;
    case UIInterfaceOrientationLandscapeLeft:{

        NSLog(@"rotate to LandscapeLeft");
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
       //     self.coverflow.frame=CGRectMake(0, 0, height+20, width-20);
            self.docView.frame=CGRectMake(0, 50, height+20, width-70);
            self.toolbar.frame=CGRectMake(0, 0,height+20 , 50);
            for (UIView * view in [toolbar subviews]) {
                if ([view isKindOfClass:[UIButton class]] && view.tag==kBackButtonTag)  {
                    view.frame=CGRectMake(height-60, 6, 50, 36);
                    NSLog(@"button %@",[view description]);
                }else if([view isKindOfClass:[UIButton class]] && view.tag==kReloadButtonTag){
                    view.frame=CGRectMake(height-160, 6, 80,36 );
                }
            }
            [coverflow setFrame:CGRectMake(0, 0 , height+20, width/2-50)];
            [titleLabel setFrame:CGRectMake(height/2-40,width/2-80, 100, 20)];
            if ([[[UIDevice currentDevice]model]isEqualToString:@"iPad"]) {
                self.viewer.frame=CGRectMake(0, 0, 1024, 748);
            }else{
                self.viewer.frame=CGRectMake(0, 0, 480, 320);
            }
        }

        i = 90;
    }break;
    case UIInterfaceOrientationLandscapeRight:{
        NSLog(@"rotate to LandscapeRight");
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
        //    self.coverflow.frame=CGRectMake(0, 0, height+20, width-20);
            self.docView.frame=CGRectMake(0, 50, height+20, width-70);
            self.toolbar.frame=CGRectMake(0, 0,height+20 , 50);
            for (UIView * view in [toolbar subviews]) {
                if ([view isKindOfClass:[UIButton class]] && view.tag==kBackButtonTag)  {
                    view.frame=CGRectMake(height-60, 6, 50, 36);
                }
                else if([view isKindOfClass:[UIButton class]] && view.tag==kReloadButtonTag){
                    view.frame=CGRectMake(height-160, 6, 80,36 );
                }
            }
            [coverflow setFrame:CGRectMake(0, 0 , height+20, width/2-50)];
            [titleLabel setFrame:CGRectMake(height/2-40,width/2-80, 100, 20)];
            if ([[[UIDevice currentDevice]model]isEqualToString:@"iPad"]) {
                self.viewer.frame=CGRectMake(0, 0, 1024, 748);
            }else{
                self.viewer.frame=CGRectMake(0, 0, 480, 320);
            }
        }

        i = -90;
    }break;
}

//[webViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
// [self.view setNeedsDisplay];
//   NSLog(@"coverflowView :%@",[self.coverflow description]);
   NSLog(@"webview :%@",[viewer description]);
    [viewer stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"window.__defineGetter__('orientation',function(){return %f;});",i]];
    [viewer stringByEvaluatingJavaScriptFromString:@"var e = document.createEvent('Events'); e.initEvent('orientationchange', true, false); document.dispatchEvent(e); "];    
}




- (void)viewDidLoad {
self.view.clipsToBounds=YES;
self.view.autoresizesSubviews=YES;
// self.view.autoresizingMask=UIViewAutoresizingNone;

viewer=[[UIWebView alloc]initWithFrame:self.view.bounds];

[self.view addSubview:viewer];
 viewer.delegate=self;
 viewer.scalesPageToFit=NO;
 viewer.autoresizesSubviews=NO;
 viewer.autoresizingMask=UIViewAutoresizingNone;
viewer.dataDetectorTypes=0;
// viewer.autoresizingMask=UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
NSLog(@"webView :%@",[viewer description]);
//  [viewer setFrame:CGRectMake(0, self.view.bounds.size.height/2 , self.view.bounds.size.width, self.view.bounds.size.height/2)];
//  [viewer setBounds:CGRectMake(0, self.view.bounds.size.height/2 , self.view.bounds.size.width, self.view.bounds.size.height/2)];

UIScrollView *scroller=[viewer.subviews objectAtIndex: 0];
if (scroller) {
    scroller.alwaysBounceVertical=NO;
    scroller.bounces=NO;
    scroller.scrollEnabled=NO;   
}

[self viewHomePage];
//[self createCoverFlowView];
[self createPopView];
//[self setHomeButtonPosition]; 
//[self setSettingButtonPosition];

#if __IPHONE_OS_VERSION_MIN_REQUIRED > 30000
UILongPressGestureRecognizer* longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
[self.view addGestureRecognizer:longPress];
longPress.minimumPressDuration=2.0;
longPress.delegate = self;
longPress.cancelsTouchesInView = NO;
longPress.allowableMovement=20;
[longPress release];  

UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];
singleTap.delegate = self;
singleTap.cancelsTouchesInView = NO;
[singleTap release];  
#endif
//[viewer setOpaque:YES];      //透明
[super viewDidLoad];

}

7 个答案:

答案 0 :(得分:51)

我花了大约两天试图追踪这个问题,因为我遇到了完全相同的问题。我发现我的视图如果以纵向模式开始,将正确调整为横向。但是,如果我在横向模式下启动视图,它将在纵向中保持相同的大小。

如果您的视图是设备的整个宽度,只需添加以下元标记即可。

<meta name="viewport" content="width=device-width" />

但是,就我而言,我们的UIWebView是一个非标准的大小。将视口设置为device-width只会让它变得更糟!通过使用javascript动态设置视口,我能够正常运行。这应该在UIWebViews父视图的layoutSubviews期间完成。您可以在willRotateToInterfaceOrientation中执行此操作,但我发现如果您使用willRotate,则可能无法正确设置某些大小和接口。首先尝试一下,看看动画是如何工作的。

代码只是将视口大小设置为当前帧大小。您正在查看的HTML必须已有meta viewport标记(如上所述)。如果您无法编辑HTML,还可以通过javascript添加其他方法。最简单的方法是将元标记添加到<head>标记中。然后在正确设置框架后使用以下代码:

 // assuming your self.viewer is a UIWebView
[self.viewer stringByEvaluatingJavaScriptFromString:
     [NSString stringWithFormat:
     @"document.querySelector('meta[name=viewport]').setAttribute('content', 'width=%d;', false); ",
      (int)self.viewer.frame.size.width]];

如果您不希望用户缩放,或者您想设置最大比例,则可以添加其他视口项目。这最终使视图对我们的UIWebView正常运行。

答案 1 :(得分:1)

我有一个类似的问题,仍然无法找到真正的解决方案。我在UIWebView上调用reload来解决这个问题,方法是让scale页面适合。

[webView reload];

答案 2 :(得分:1)

如果其他人有同样的问题,只需给出一个单挑。

webview不会正确调整大小,因为HTML已经呈现(我不确定这是否完全正确,可能只是webview本身的错误),但无论如何。我制作了一个调整webview html体宽的方法:

- (void) resizeHtml
{
     NSString *jsString = [[NSString alloc] initWithFormat:@"document.getElementsByTagName('html')[0].style.width= '%dpx'", (int) _frame.size.width];

    [self.webView stringByEvaluatingJavaScriptFromString:jsString];
    [jsString release];
}

这似乎在iphone上运行得很好,但在ipad上我必须这样做

- (void) reloadHtml
{
    NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML"];

    if(html == nil || [html isEqualToString:@""] || [html length] < 100)
        [self.webView reload];

    [self.webView loadHTMLString:html baseURL:[NSURL URLWithString:@"some base url"]];
}

您也可以使用[self.webview reload],但这会向服务器发出另一个请求,我认为这很糟糕; - )

我希望这有帮助!

答案 3 :(得分:1)

我赞成@ christophercotton的回应,因为它有效。但我也发现我可以在不控制webview对象的情况下解决类似的问题。他的解决方案让我在正确的轨道上解决了我的问题。

        var el = $('meta[name=viewport]');
    if (window.orientation == 90 || window.orientation == -90) {
        el.attr('content', 'width=device-height');
    } else {
        el.attr('content', 'width=device-width');
    }

这适用于iOS。没有在android中尝试过(对于使用PhoneGap之类的人)。

答案 4 :(得分:0)

我还遇到了从横向切换到纵向时UIWebView内容无法正确调整大小的问题。

在狩猎了一段时间后,我找到了答案:

“我发现处理这个的一种方法是在调整大小后重新加载内容。当我说”重新加载“时,我不是指UIWebView上的内置重载功能,我的意思是对loadHTMLString的实际调用:baseURL :(或者您最初用于加载内容的方法)。“ Agent Gold's post on Apple Support forum

答案 5 :(得分:0)

我遇到了同样的问题。

对我有用的解决方案是设置:

webView.scalesPageToFit = YES;

答案 6 :(得分:0)

我试过Christoper's answer,将他的OOC代码翻译成Swift,但没有工作。

最后,如果屏幕尺寸发生变化,我必须让UIWebView重新加载网页。它可能是一个黑客,但无论如何都有效。希望这个答案能够或多或少地帮助Swift开发人员。以下功能属于您的UIViewController

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
    coordinator.animateAlongsideTransition(nil, completion: {context in
        self.webView.reload()            
    })
}