UIWebView не изменяет размер при изменении ориентации?

Я добавляю webview, заголовок и coverflowView в представлении viewcontroller в качестве своих подзонов, я хочу, чтобы он менял размер при изменении ориентации. Я изменил рамку веб-просмотра в этом методе:

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

его содержимое изменило размер при повороте iPad от ориентацииLandscape к ориентацииPortrait или от ориентацииPortrait к ориентацииLandscape, если я запускаю приложение с портретной ориентацией, но это так странно, что его содержимое не изменяет размер, когда я запускаю приложение с альбомной ориентацией.. Но NSLog показывает, что кадр изменился. Что касается titleLabel и coverflowView, они правильно изменяют размер. Я сомневаюсь, что это из-за css? Я использую css для управления стилем контента в соответствии с высотой и шириной webview. Кто-нибудь может помочь мне найти причину? код ниже:

- (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];

}

Ответы

Ответ 1

Я потратил около двух дней, пытаясь отследить эту проблему, так как у меня была такая же проблема. Я обнаружил, что мой взгляд, если он начался в режиме портрета, правильно изменит размер на Пейзаж. Но, если бы я начал просмотр в ландшафтном режиме, он сохранил бы тот же размер в Portrait.

Если ваше представление представляет собой всю ширину устройства, просто будет добавлен следующий метатег.

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

Но в моем случае наш UIWebView является нестандартным размером. Настройка окна просмотра на device-width только делает его хуже! Я смог правильно все обработать, установив динамический просмотр с помощью javascript. Это должно быть сделано во время просмотра родительского представления UIWebViewsSubviews. Вы можете сделать это в 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.

Ответ 2

У меня есть аналогичная проблема и до сих пор не могу найти реального решения. Я вызываю перезагрузку в UIWebView, чтобы обойти эту проблему, указав страницу весов.

[webView reload];

Ответ 3

Просто дайте хэдшоп, если у других такая же проблема.

Веб-просмотр не будет правильно изменен, потому что HTML уже отображен (я не уверен, что это полностью верно, может быть просто ошибкой в ​​самом веб-обозревателе), но в любом случае. Я создал метод, который изменяет размер тела html в webview:

- (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], но это сделало бы другой запрос на сервер, и я думаю, что это плохо; -)

Надеюсь, это поможет!

Ответ 4

Я поддержал ответ @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. Не пробовал в андроиде (для тех, кто пользуется телефоном).

Ответ 5

У меня также возникла проблема с содержимым UIWebView, не соответствующим правильному размеру при переключении с пейзажа на портрет.

После охоты на некоторое время я нашел ответ:

"Один из способов, который я нашел для этого, - перезагрузить контент после изменения размера. Когда я говорю" перезагрузить ", я не имею в виду встроенную функцию перезагрузки в UIWebView, я имею в виду фактический вызов для загрузкиHTMLString: baseURL: (или какой бы метод вы ни использовали для загрузки вашего контента изначально). Сообщение агента Gold на форуме поддержки Apple

Ответ 6

У меня была такая же проблема.

Решение, которое сработало для меня, заключалось в том, чтобы установить:

webView.scalesPageToFit = YES;

Ответ 7

Я попробовал Кристопер ответить, переведя свой код 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()            
    })
}