【问题标题】:How can I open modal view without loosing data in target controller?如何打开模态视图而不丢失目标控制器中的数据?
【发布时间】:2012-02-02 14:27:04
【问题描述】:

问题是我不知道如何在推送或呈现为模态视图后保存接收到的控制器数据。我正在使用故事板、ARC、iOS5。当项目使用 xib 时一切正常。我在目标 ViewController 中有 UIWebView,我需要它来打开传输的 url 以进行 twitter OAuth 身份验证。这是 TweetViewController 的代码,我从这里调用 WebViewController 的函数。然后我尝试在 UIWebController 所在的位置展示 UIViewController。但是在我传输 url 之后,它会忘记这个数据。所以在 ViewDidLoad 函数中,NSURL 为空。

// TweetViewController.h
#import <UIKit/UIKit.h>
#import "RSTwitterEngine.h"
#import "WebViewController.h"

@interface TweetViewController : UIViewController <RSTwitterEngineDelegate, WebViewControllerDelegate>

@property (strong, nonatomic) RSTwitterEngine *twitterEngine;
@property (strong, nonatomic) WebViewController *leWebView;

@property (unsafe_unretained, nonatomic) IBOutlet UITextView *textView;
@property (unsafe_unretained, nonatomic) IBOutlet UIBarButtonItem *sendButton;
@property (unsafe_unretained, nonatomic) IBOutlet UILabel *statusLabel;

- (IBAction)sendTweet:(id)sender;
- (void)swipedRight:(UIGestureRecognizer *)recognizer;

@end

发送 url 数据的 TweetViewController.m 的一部分:

#pragma mark - RSTwitterEngine Delegate Methods

- (void)twitterEngine:(RSTwitterEngine *)engine needsToOpenURL:(NSURL *)url
{
    self.leWebView = [_leWebView initWithURL:url];
    self.leWebView.delegate = self;
    [self performSegueWithIdentifier:@"LeWebSegue" sender:self];      
    //[self presentModalViewController:self.leWebView animated:YES];
}

所以这里是 WebViewController 的关键部分:

//  WebViewController.h

#import <UIKit/UIKit.h>

@protocol WebViewControllerDelegate;

@interface WebViewController : UIViewController <UIWebViewDelegate>

@property (retain, nonatomic) NSURL *currentURL;

@property (assign, nonatomic) id <WebViewControllerDelegate> delegate;
@property (retain, nonatomic) IBOutlet UIWebView *leWebView;
@property (retain, nonatomic) IBOutlet UIActivityIndicatorView *leActivityIndicator;

- (id)initWithURL:(NSURL *)url;
- (IBAction)ActionNoMore:(id)sender;
@end

@protocol WebViewControllerDelegate <NSObject>

- (void)dismissWebView;
- (void)handleURL:(NSURL *)url;

@end

和 WebViewController.m

#import "WebViewController.h"
#import "AppDelegate.h"

@implementation WebViewController

@synthesize delegate = _delegate;
@synthesize currentURL = _currentURL;
@synthesize leWebView = _leWebView;
@synthesize leActivityIndicator = _leActivityIndicator;

#pragma mark - Initialization
// ======= Here is that function which recieves url ========
- (id)initWithURL:(NSURL *)url
{
    self = [self.storyboard instantiateViewControllerWithIdentifier:@"WebView"];
    NSLog(@"WebViewController initWithURL called. Recieved url = %@", url);

    if (self) {
        self.currentURL = url;
        self.delegate = nil;
    }

    return self;

}

#pragma mark - View Lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"WebViewController viewDidLoad called. currentURL = %@", self.currentURL);

    self.leWebView.scalesPageToFit = YES;
    [self.leWebView loadRequest:[NSURLRequest requestWithURL:self.currentURL]];     
}

- (void)viewDidUnload
{
    [self setLeWebView:nil];
    [self setLeActivityIndicator:nil];

    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - UIWebView Delegate Methods

- (BOOL)LeWebView:(UIWebView *)LeWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    if ([request.URL.scheme isEqualToString:@"rstwitterengine"] && (self.delegate)) {
        if (self.leActivityIndicator) [self.leActivityIndicator stopAnimating];
        [self.delegate handleURL:request.URL];
        return NO;
    } else {
        return YES;
    }
}

- (void)webViewDidStartLoad:(UIWebView *)LeWebView
{
    if (self.leActivityIndicator) [self.leActivityIndicator startAnimating];
}

- (void)webViewDidFinishLoad:(UIWebView *)LeWebView
{
    if (self.leActivityIndicator) [self.leActivityIndicator stopAnimating];
}

- (void)LeWebView:(UIWebView *)LeWebView didFailLoadWithError:(NSError *)error
{
    if (self.leActivityIndicator) [self.leActivityIndicator stopAnimating];

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                    message:[error localizedDescription]
                                                   delegate:nil
                                          cancelButtonTitle:@"Dismiss"
                                          otherButtonTitles:nil];
    [alert show];
}

#pragma mark - Custom Methods


- (IBAction)ActionNoMore:(id)sender {
    if (self.delegate) [self.delegate dismissWebView];

}
@end

当我尝试加载该视图时,我收到了 WebViewController viewDidLoad 调用的日志消息。 currentURL = (null)

【问题讨论】:

    标签: objective-c xcode ios5 uiwebview storyboard


    【解决方案1】:

    我注意到您正在调用情节提要以在 initWithURL 方法中创建视图控制器。创建对象的正常方式是先执行 alloc,然后再执行 initWithURL。 alloc 方法在内存中创建对象,initWithURL 配置对象。如果您调用 alloc,然后在 initWithURL 中调用 instanceViewControllerWithIdentifier,则可能会造成内存泄漏,因为 instanceViewControllerWithIdentifier 在调用时也会分配内存。然后将“self”设置为另一个地址。

    这可能会在您运行 instantiateViewControllerWithIdentifier 时造成混乱。很难说。您可能应该在父视图控制器中运行 instantiateViewControllerWithIdentifier,然后推送您的视图控制器,然后设置您的 URL,因为 UIWebView 仅在显示时实例化,而不是在创建视图控制器时实例化。

    HTH

    【讨论】:

    • 很高兴你找到了它。但为了安全起见,您可能还想检查 initWithURL 方法周围的内存泄漏。我不能确定,但​​是当您运行情节提要的 instantiateViewControllerWithIdentifier 时,您可能会泄漏。祝你好运!
    猜你喜欢
    • 2015-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多