UIPopoverController不断重新加载UIWebView

时间:2013-11-22 21:10:54

标签: ios ipad uiwebview ios7 uipopovercontroller

我有一个UIPopoverController,我正在使用ViewController加载来保存UIWebView。当我按下按钮呈现Popover时,网页加载正常。我也可以解雇Popover一样好。当我按一个按钮再次显示Popover时,UIWebView会重新加载。有没有办法在ViewController中维护/保持WebView的状态,以便在弹出窗口被显示/解除时内容保持不变?

也许另一个问题是,当Popover被解雇时,我的ViewController被擦除了吗?我不相信它应该是因为它不是局部变量,但我不确定我是否对UIPopoverController的行为有误解。

以下相关代码:

在我的主ViewController中:

_popoverMenuVC  = [[TBPopoverMenuViewController alloc] init];
_popoverMenuVC.delegate = self;
_popoverMenuVC.contentSizeForViewInPopover = CGSizeMake(300, 300*(1+sqrt(5)/2.));
_popoverCtr = [[UIPopoverController alloc] initWithContentViewController:_popoverMenuVC];

我的按钮代码:

- (void)menuBtnPressed:(id)sender
{
if (IS_IPAD) {
    UIButton *btn = (UIButton*)sender;
    if (!_popoverCtr.isPopoverVisible) {


        //set url for popover webview
        _popoverMenuVC.popoverURL = @"http://www.google.com";

        // show popover
        [_popoverCtr setPopoverContentSize:CGSizeMake(300, 300*(1+sqrt(5)/2.))];
        [_popoverCtr presentPopoverFromRect:btn.frame
                                     inView:self.view
                   permittedArrowDirections:UIPopoverArrowDirectionDown
                                   animated:YES];
    } else {


        // hide popover
        [_popoverCtr dismissPopoverAnimated:YES];
    }
}

我的popoverMenuVC代码:

-(void) viewDidAppear:(BOOL)animated{
[self setupUIs];
}

- (void)setupUIs
{
//  webview
wv = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 300, 300*(1+sqrt(5)/2.))];

//activity indicator
self.activityIndicator = [[UIActivityIndicatorView alloc]      initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
self.activityIndicator.frame = CGRectMake(0.0, 0.0, 40, 40);
self.activityIndicator.center = self.view.center;

// darkview for activity indicator
self.darkView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,300, 300*(1+sqrt(5)/2.))];
[self.darkView setBackgroundColor:[UIColor blackColor]];
[self.darkView setAlpha:0.4];

wv.delegate = self;
wv.scalesPageToFit = YES;
wv.scrollView.bounces = NO; //get rid of bounce for popover menu

[self.view addSubview:wv];

}

一些代表处理活动指标:

#pragma mark Activity Indicator

- (void) showLoadingIndicator
{
[self.view insertSubview:self.darkView aboveSubview:self.view];
[self.view insertSubview:self.activityIndicator aboveSubview:self.darkView];
[self.activityIndicator startAnimating];
}

- (void) hideLoadingIndicator
{
[self.activityIndicator stopAnimating];
[self.activityIndicator removeFromSuperview];
[self.darkView removeFromSuperview];
}

#pragma mark UIWebView Delegates

-(void)webViewDidStartLoad:(UIWebView *)webView{
NSLog(@"Webview is starting to load");
[self showLoadingIndicator];
}

-(void)webViewDidFinishLoad:(UIWebView *)webView{
NSLog(@"request: %@", [[webView request] description]);
if(!webView.loading){
    NSLog(@"Webview has finished loading");
    [self hideLoadingIndicator];
}
}

我有一个非常类似的实现这个工作的iPhone,显然没有Popover,只是与ViewControllers,它似乎工作正常。想知道这是否必须与PopoverController本身一起工作......

感谢您的帮助!

修改1:

我将以下代码移到了我的主ViewController:

_popoverMenuVC  = [[TBPopoverMenuViewController alloc] init];
_popoverMenuVC.wv = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 300, 300*(1+sqrt(5)/2.))];
_popoverMenuVC.wv.scalesPageToFit = YES;
_popoverMenuVC.wv.scrollView.bounces = NO; //get rid of bounce for popover menu
_popoverMenuVC.req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];
_popoverCtr = [[UIPopoverController alloc] initWithContentViewController:_popoverMenuVC];

我的viewDidAppear函数中没有任何内容,我现在将其移至viewDidLoad:

- (void)viewDidLoad
{
[super viewDidLoad];
wv.delegate = self;
[wv loadRequest:req];
[self.view addSubview:wv];
}

但WebView不再加载(我认为与此问题有关:iOS 7 UIWebView doesn't load webpage

将上述代码从ViewDidLoad移到viewDidAppear将加载我的WebView,但同样的重新加载问题仍然存在。

任何额外的帮助将不胜感激!

编辑2:

我做了一些代码重构,以便专注于可能导致此行为的原因:

在我的主ViewController中,我正在设置我的PopoverViewController及其WebView,并将其设置为我们的UIPopoverController的init内容:

_popoverMenuVC  = [[TBPopoverMenuViewController alloc] init];
_popoverMenuVC.wv = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 300, 300*(1+sqrt(5)/2.))];        
_popoverMenuVC.wv.scalesPageToFit = YES;
_popoverMenuVC.wv.scrollView.bounces = NO; //get rid of bounce for popover menu
_popoverMenuVC.req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];
[_popoverMenuVC.view addSubview:_popoverMenuVC.wv];
_popoverCtr = [[UIPopoverController alloc] initWithContentViewController:_popoverMenuVC];

所有这一切都发生在我的TBPopoverMenuViewController代码之外。

在我的TBPopoverMenuViewController.h中,我为wv和req设置了一个属性。

在我的TBPopoverMenuViewController.m中,我合成了我的wv,但不是我的请求。

这是我的viewDidLoad,我将wv的委托设置为self。

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view setBackgroundColor:[UIColor whiteColor]];
wv.delegate = self;
//    [wv loadRequest:_req];

}

在viewDidAppear中,这是我加载请求的地方。

-(void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:NO];
[self setupActivityIndicator];
[wv loadRequest:_req];
}

尝试在其他任何地方加载我的请求,在视图中加载,或者甚至在主ViewController中,它不会在弹出窗口中加载请求。它似乎只想在viewDidAppear函数中发生。

此外,当我第二次尝试加载弹出窗口时,您可以看到之前加载了页面的wv,但之后几乎是在请求似乎重新加载到该webview之上。

有没有人有解决方案?当popover解散并重新呈现时,如何维护我的webview。在非弹出式实现中,这似乎在iPhone上运行良好,让我觉得iPad / iOS7 / UIPopoverControllers有一些我缺少的东西。

任何帮助将不胜感激!

编辑3:

使用Xcode的Instruments工具进行一些调试后,我意识到调用:

[wv loadRequest:_req];

在我的ViewController的viewDidAppear中导致内存泄漏!因此,在我的UIWebView重新加载问题以及我在何处/如何加载请求时,似乎有一些必要的东西。正如我之前提到的,我已经尝试在我的主视图控制器中调用我的Popover的ViewController之外的loadRequest,没有运气。我也尝试在viewDidLoad中调用loadRequest,但也没有运气。

在弹出窗口后,我能够在menuBtnPressed函数中成功调用loadRequest:

- (void)menuBtnPressed:(id)sender
{
if (IS_IPAD) {
    popOverBtn = (UIButton*)sender;
    if (!_popoverCtr.isPopoverVisible) {

        [_popoverCtr setPopoverContentSize:CGSizeMake(300, 300*(1+sqrt(5)/2.))];   
        [_popoverCtr presentPopoverFromRect:popOverBtn.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
        [_popoverMenuVC.wv loadRequest:_popoverMenuVC.request];

    } else {
        // hide popover
        [_popoverCtr dismissPopoverAnimated:YES];
    }

归结为我可以在popover中为UIWebView成功调用loadRequest的两个地方:

-ViewController中的viewDidApepar

- 按下按钮后显示我的弹出窗口

根据Xcode的Instruments工具,这两个似乎仍然会导致内存泄漏。从演示回来时,我仍然无法让我的UIWebView维持/保持状态 - >解雇 - >重新呈现弹出窗口。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

每次viewDidAppear完成时,都会调用popover的present方法。

因此,每次弹出窗口时,当前代码都会添加一个 new UIWebView,它将转到默认网址(包含之前显示的所有先前网页视图)。< / p>

一些更改应该可以为您提供所需的行为:

  1. 在弹出式内容视图控制器中,将来自setupUIs的呼叫从viewDidAppear移至viewDidLoad
  2. 在主视图控制器中,将popoverURL的设置移动到弹出窗口内容视图控制器首先创建的位置(在分配+ init之后)。

答案 1 :(得分:0)

事实证明我的问题的答案是......两次调用loadRequest。

//setup popover menu vc
    _popoverMenuVC  = [[TBPopoverMenuViewController alloc] init];
    _popoverMenuVC.wv = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 300, 300*(1+sqrt(5)/2.))];
    _popoverMenuVC.delegate = self;
    _popoverMenuVC.wv.scalesPageToFit = YES;
    _popoverMenuVC.wv.scrollView.bounces = NO; //get rid of bounce for popover menu
    _popoverMenuVC.request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/"]];
    [_popoverMenuVC.wv loadRequest:_popoverMenuVC.request]; //first request
    [_popoverMenuVC.view addSubview:_popoverMenuVC.wv];
    _popoverCtr = [[UIPopoverController alloc] initWithContentViewController:_popoverMenuVC];
    [_popoverMenuVC.wv loadRequest:_popoverMenuVC.request]; // second request

这会导致我想要的行为。 UIWebView在加载页面的PopoverViewController中加载,当我出现时 - > dismiss-&GT;重新呈现popover,页面UIWebView是我离开它的地方。我不知道为什么这个工作,但它似乎是一个错误或黑客,不得不两次调用该函数。根据Xcode中的Instruments工具集,loadRequest似乎也会导致内存泄漏。

所以我解决了我的问题,但我仍然有点困惑为什么这是解决方案。幸运的是我偶然发现了......

任何有经验的人都会表示赞赏!