如何打开模态视图而不丢失目标控制器中的数据?
问题是我不知道如何在推送或呈现为模态视图后保存收到的控制器数据。我正在使用故事板、ARC、iOS5。当项目使用 xib 时,一切工作正常。我在目标 ViewController 中有 UIWebView,我需要它来打开传输的 url 以进行 twitter OAuth 身份验证。这是 TweetViewController 的代码,我从其中调用 WebViewController 的函数。然后我尝试呈现 UIWebController 所在的 UIViewController 。但在我传输 url 后,它会忘记此数据。因此在 ViewDidLoad 函数中 NSURL 为 null。
// 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
TweetViewController.m 发送 url 数据的部分:
#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 调用的日志消息。当前URL =(空)
The problem is that I have no idea how can I save received controller data after pushing it or presenting as modal view. I am using storyboard, ARC, iOS5. When project was using xib everything worked fine. I have UIWebView in target ViewController and I need it to open transmitted url for twitter OAuth authentication. Here is code of TweetViewController, from where I call function of WebViewController. Then I try to present UIViewController where UIWebController is. But after i transmit url, it forgets this data. So on ViewDidLoad function the NSURL is null.
// 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
Part of TweetViewController.m which sends url data:
#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];
}
So here is WebViewController key parts:
// 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
and 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
At all, when I try to load that view, i receive log messages that WebViewController viewDidLoad called. currentURL = (null)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我注意到您正在调用故事板以在 initWithURL 方法中创建视图控制器。创建对象的正常方法是先进行分配,然后进行 initWithURL。 alloc 方法在内存中创建对象,initWithURL 配置该对象。如果您正在调用 alloc,然后在 initWithURL 中调用 instantiateViewControllerWithIdentifier,则可能会造成内存泄漏,因为 instantiateViewControllerWithIdentifier 在调用时也会分配内存。然后你将“self”设置为另一个地址。
当您运行 instantiateViewControllerWithIdentifier 时,这可能会导致混乱。很难说。您可能应该在父视图控制器中运行 instantiateViewControllerWithIdentifier ,然后推送视图控制器,然后设置 URL,因为 UIWebView 仅在显示时实例化,而不是在创建视图控制器时实例化。
华泰
Something I noticed is that you are calling the storyboard to create your view controller in the initWithURL method. The normal way an object is created is the do an alloc and then the initWithURL. The alloc method creates the object in memory and the initWithURL configures the object. If you are calling the alloc and then in your initWithURL you are calling the instantiateViewControllerWithIdentifier you may be creating a memory leak since instantiateViewControllerWithIdentifier also allocates memory when it's called. Then you set the "self" to another address.
This may be causing confusion when you run instantiateViewControllerWithIdentifier. It's difficult to say. You should probably run the instantiateViewControllerWithIdentifier in the parent view controller and then push your view controller and then set your URL since UIWebViews only instantiate when they are displayed and not when the view controller is created.
HTH