ios - UIPopoverController不断重新加载UIWebView

标签 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];

}

一些 Activity 指标的代表:
#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的初始化内容:
_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之后。

有没有人有办法解决吗?当弹出窗口消失并重新显示时,如何维护我的Web视图。在非弹出窗口实现中,这似乎可以在iPhone上正常工作,这使我认为iPad / iOS7 / UIPopoverControllers缺少某些功能。

任何帮助,将不胜感激!

编辑3:

在使用Xcode的Instruments工具进行调试之后,我意识到了调用:
[wv loadRequest:_req];

在我的ViewController的viewDidAppear中导致内存泄漏!因此,在UIWebView重新加载以及我的请求加载位置/方式方面,似乎存在一些必不可少的问题。如前所述,我尝试在主View Controller的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];
    }

归结为我可以实际在弹出窗口中成功为UIWebView调用loadRequest的两个地方:

-in ViewController中的viewDidApepar

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

根据Xcode的Instruments工具,这两种方法似乎仍然会导致内存泄漏。从呈现->关闭->重新呈现弹出框时,我仍然无法使UIWebView保持/持久状态。

有什么建议么?

最佳答案

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

因此,每次显示弹出窗口时,当前代码都会在默认网址中添加一个新的UIWebView(下面带有来自先前呈现的所有先前Web视图)。

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

  • 在弹出内容视图控制器中,将对setupUIs的调用从viewDidAppear移至viewDidLoad
  • 在主视图控制器中,将popoverURL的设置移动到第一次创建弹出式内容视图控制器的位置(在alloc + init之后)。
  • 关于ios - UIPopoverController不断重新加载UIWebView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20154551/

    相关文章:

    ios - 如何在iOS中获取默认的系统颜色?

    ipad - 增加 iPad 10MB 缓存限制

    ios - 应用程序试图以模态方式呈现事件 Controller iOS 6.0.2

    ios - 在 iOS 上创建良好的自定义表情聊天体验

    ios - Swift 中的 UITextField `setText`

    ios - 如何让 View 像 UITabBar 应用程序一样保持事件状态?

    ios - AVAudioPlayer 仅在 iOS 模拟器上失败

    iphone - 重置内容插入后如何设置滚动偏移?

    iphone - uiwebview 到 uiview

    iphone - 如何获取从标准 UIViewController 中调用的 UIWebView 的 UIScrollView 委托(delegate)方法?