模态视图的 iPad 问题:创建视图控制器后模态视图标签为空
Posted
技术标签:
【中文标题】模态视图的 iPad 问题:创建视图控制器后模态视图标签为空【英文标题】:iPad issue with a modal view: modal view label null after view controller is created 【发布时间】:2010-06-01 03:34:53 【问题描述】:这是一个奇怪的问题。我为我的模态视图创建了一个带有 nib 文件的视图控制器。在那个视图上有一个标签、数字和文本视图。当我从源视图创建视图时,我尝试设置标签,但它显示标签是null (0x0)
。有点奇怪......有什么建议吗?现在让我们看一下代码(我把所有的代码都放在这里,因为这比我能解释的要多):
模态视图控制器 - 在 IB 中,标签连接到 UILabel 对象:
@implementation ModalViewController
@synthesize delegate;
@synthesize goalLabel, goalText, goalNumber;
// Done button clicked
- (void)dismissView:(id)sender
// Call the delegate to dismiss the modal view
if ([delegate respondsToSelector:@selector(didDismissModalView: newText:)])
NSNumber *tmpNum = goalNumber;
NSString *tmpString = [[NSString alloc] initWithString:[goalText text]];
[delegate didDismissModalView:tmpNum newText:tmpString];
[tmpNum release];
[tmpString release];
- (void)cancelView:(id)sender
// Call the delegate to dismiss the modal view
if ([delegate respondsToSelector:@selector(didCancelModalView)])
[delegate didCancelModalView];
-(void) setLabelText:(NSString *)text
[goalLabel setText:text];
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
// Custom initialization
return self;
*/
-(void) viewWillAppear:(BOOL)animated
[super viewWillAppear:animated];
// bring up the keyboard....
[goalText becomeFirstResponder];
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
[super viewDidLoad];
// set the current goal number to -1 so we know none was set
goalNumber = [NSNumber numberWithInt: -1];
// Override the right button to show a Done button
// which is used to dismiss the modal view
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:@selector(dismissView:)] autorelease];
// and now for the cancel button
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:@selector(cancelView:)] autorelease];
self.navigationItem.title = @"Add/Update Goals";
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
// Overriden to allow any orientation.
return YES;
- (void)didReceiveMemoryWarning
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
- (void)viewDidUnload
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
- (void)dealloc
[super dealloc];
@end
这里是创建视图控制器、设置变量和显示的地方:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
// put a checkmark....
UITableViewCell *tmpCell = [tableView cellForRowAtIndexPath:indexPath];
[tmpCell setAccessoryType:UITableViewCellAccessoryCheckmark];
// this is where the popup is gonna popup!
// ===> HEre We Go!
// Create the modal view controller
ModalViewController *mdvc = [[ModalViewController alloc] initWithNibName:@"ModalDetailView" bundle:nil];
// We are the delegate responsible for dismissing the modal view
[mdvc setDelegate:self];
// Create a Navigation controller
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:mdvc];
// set the modal view type
navController.modalPresentationStyle = UIModalPresentationFormSheet;
// set the label for all of the goals....
if (indexPath.section == 0 && indexPath.row == 0)
[mdvc setLabelText:[[[NSString alloc] initWithString:@"Long Term Goal 1:"] autorelease]];
[mdvc setGoalNumber:[NSNumber numberWithInt:1]];
if (indexPath.section == 0 && indexPath.row == 1)
[mdvc setLabelText:[[[NSString alloc] initWithString:@"Long Term Goal 2:"] autorelease]];
[mdvc setGoalNumber:[NSNumber numberWithInt:2]];
if (indexPath.section == 0 && indexPath.row == 2)
[mdvc setLabelText:[[[NSString alloc] initWithString:@"Long Term Goal 3:"] autorelease]];
[mdvc setGoalNumber:[NSNumber numberWithInt:3]];
if (indexPath.section == 0 && indexPath.row == 3)
[mdvc setLabelText:[[[NSString alloc] initWithString:@"Long Term Goal 4:"] autorelease]];
[mdvc setGoalNumber:[NSNumber numberWithInt:4]];
if (indexPath.section == 1 && indexPath.row == 0)
[mdvc setLabelText:[[[NSString alloc] initWithString:@"Short Term Goal 1:"] autorelease]];
[mdvc setGoalNumber:[NSNumber numberWithInt:5]];
if (indexPath.section == 1 && indexPath.row == 1)
[mdvc setLabelText:[[[NSString alloc] initWithString:@"Short Term Goal 2:"] autorelease]];
[mdvc setGoalNumber:[NSNumber numberWithInt:6]];
if (indexPath.section == 1 && indexPath.row == 2)
[mdvc setLabelText:[[[NSString alloc] initWithString:@"Short Term Goal 3:"] autorelease]];
[mdvc setGoalNumber:[NSNumber numberWithInt:7]];
if (indexPath.section == 1 && indexPath.row == 3)
[mdvc setLabelText:[[[NSString alloc] initWithString:@"Short Term Goal 4:"] autorelease]];
[mdvc setGoalNumber:[NSNumber numberWithInt:8]];
// show the navigation controller modally
[self presentModalViewController:navController animated:YES];
// Clean up resources
[navController release];
[mdvc release];
// ==> Ah... we are done...
【问题讨论】:
【参考方案1】:答案是盯着我的脸!
这是我所做的:
为委托添加了一个新功能
@protocol ModalViewControllerDelegate <NSObject>
@required
- (void)didDismissModalView:(NSNumber *)goalNbr newText:(NSString *)textToSave;
- (void)didCancelModalView;
- (void)willShow:(id)theView;
@end
在viewWillAppear
函数中,我添加了以下内容:
if ([delegate respondsToSelector:@selector(willShow:)])
[delegate willShow:self];
这允许完全访问将要显示的模态视图,因此我们能够更改活动模态视图中的标签、文本框和变量。
- (void)willShow:(ModalViewController *)theView
[theView.goalLabel setText:labelText];
[theView setGoalNumber:goalNumber];
[theView.goalText setText:goalText];
【讨论】:
【参考方案2】:为了完整起见,万一其他人偶然发现了这个(它帮助了我)......
模态视图控制器的接口需要定义一个变量来保存委托:
@protocol ReminderPhotoViewDelegate <NSObject>
@required
- (void)willShow:(id)theView;
@end
@interface ReminderPhotoViewController : UIViewController
id<ReminderPhotoViewDelegate> delegate;
UIImageView *reminderImage;
UILabel *reminderLabel;
@property (assign) id<ReminderPhotoViewDelegate> delegate;
@property (nonatomic, retain) IBOutlet UIImageView *reminderImage;
@property (nonatomic, retain) IBOutlet UILabel *reminderLabel;
@end
在模态控制器的实现中,一定要综合这些属性:
@implementation ReminderPhotoViewController
@synthesize reminderImage, reminderLabel;
@synthesize delegate;
无论你的“调用”控制器是什么,都必须在它自己的实现中声明对这个协议的支持:
#import "ReminderPhotoViewController.h"
@interface ReminderViewController : UIViewController <ReminderPhotoViewDelegate>
最后,当您创建模态控制器的实例时,您需要将调用类设置为其委托:
ReminderPhotoViewController *photo = [[ReminderPhotoViewController alloc] init];
[photo setDelegate:self];
这是一组更完整的声明和代码 - 这正是答案显示的内容,只是有更多的支持代码。
然后,如上所述,您的调用控制器从协议中添加方法:
- (void)willShow:(ReminderPhotoViewController *)theView
theView.reminderImage.image = selectedImage;
theView.reminderLabel.text = selectedText;
【讨论】:
以上是关于模态视图的 iPad 问题:创建视图控制器后模态视图标签为空的主要内容,如果未能解决你的问题,请参考以下文章