2013-11-22 63 views
1

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

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

下面

相关代码:

在我的主视图控制器:

_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的工作,而不酥料饼很明显,只是ViewControllers,似乎很好地工作。想知道这是否必须与PopoverController本身...

感谢您的任何帮助!

编辑1:

我搬到下面的代码到我的主视图控制器:

_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:

我为了聚焦于什么可能导致这种行为做了一些代码重构:

在我的主视图控制器,我建立我的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,但不是我的req。

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

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

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

试图加载了我的请求其他地方,鉴于没有负荷,甚至在主视图控制器,它不会加载在酥料饼的要求。它似乎只想在viewDidAppear函数中发生。

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

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

任何帮助,将不胜感激!

编辑3:

一些调试和Xcode的仪器工具后,我意识到,美其名曰:

[wv loadRequest:_req]; 

在我的ViewController结果viewDidAppear内存泄漏!所以在UIWebView重新加载以及我在何处/如何加载我的请求时,似乎有一些重要的问题。正如我之前提到的,我已经尝试在我的主View Controller中的Popover的ViewController之外调用loadRequest,但没有运气。我也尝试在viewDidLoad中调用loadRequest,但没有运气。

我能够成功调用的loadRequest我menuBtnPressed功能酥料饼提出后:

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

这可以归结为两个地其实我可以成功调用的loadRequest了一个UIWebView在我酥料饼是:

-in viewDidApepar在视图控制器

-after提出我酥料饼按下一个按钮

根据Xcode的Instruments工具,这两者似乎仍然导致内存泄漏。从展示 - >解散 - >重新展示popover时,我仍然无法让UIWebView保持/保持状态。

有什么建议吗?

回答

1

每当present完成时,就会调用弹出方法viewDidAppear

因此酥料饼,提出每一次,当前的代码添加了一个新的UIWebView都到默认的URL(包括所有从以前的礼物下方的以前的Web视图)。

一些改动应该给你你想要的行为:

  1. 在酥料饼的内容视图控制器,从viewDidAppear移动呼叫setupUIsviewDidLoad
  2. 在主视图控制器中,将popoverURL的设置移动到弹出式窗口内容视图控制器第一个的位置已创建(正好在alloc + init之后)。
+0

很好的回答!我只想强调多么糟糕,容易出错和脆弱的viewWillAppear/viewDidAppear逻辑。这些方法只能用于监视视图的状态,不能设置UI,逻辑等。 –

+0

谢谢您的及时答复!我试图实现这一点,并有几个问题: 将我的setupUI函数从viewDidAppear移动到viewDidLoad,使得setupUI中的WebView不再加载。我觉得它与这个问题有关:http://stackoverflow.com/questions/18949857/ios-7-uiwebview-doesnt-load-webpage 我也这样做了,所以URL在这里硬编码,用于测试: NSMutableURLRequest * req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@“http://www.google.com”]]; 我会尝试创建对主视图控制器的请求,看看它是否工作。 – jojohn

+0

我更新了我的帖子,最初尝试解决此问题,这似乎没有帮助。 – jojohn

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并加载页面,当我呈现 - >解除 - >重新呈现弹出窗口时,页面UIWebView就是我离开它的地方。我不知道为什么这个工程虽然,它看起来像一个错误或黑客,不得不调用该函数两次。根据Xcode中的Instruments工具集,loadRequest似乎也会导致内存泄漏。

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

任何人更经验的任何澄清将不胜感激!