我正在iOS上开发,我正在以编程方式构建我的视图。我注意到当我尝试从视图控制器访问我的视图中必须更改的变量时,它们为空。我将发布视图及其视图控制器:
RootViewController.h
#import <UIKit/UIKit.h>
@class RootView;
@interface RootViewController : UIViewController {
RootView *rootView;
}
@property (nonatomic,retain) RootView *rootView;
@end
RootViewController.m
#import "RootViewController.h"
#import "RootView.h"
@implementation RootViewController
@synthesize rootView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[rootView release];
[super dealloc];
}
- (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.
}
#pragma mark - View lifecycle
- (void)loadView{
RootView *rootV = [[RootView alloc] initWithFrame:CGRectMake(10, 10, 100, 50)];
rootV.rootViewController = self;
self.view = rootV;
[rootV release];
}
- (void)viewDidLoad{
NSLog(@"TEXT: %@",self.rootView.label.text);
self.rootView.label.text=@"HELLO!";
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
[self setRootView:nil];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end
RootView.h
#import <UIKit/UIKit.h>
@class RootViewController;
@interface RootView : UIView {
RootViewController *rootViewController;
UILabel *label;
}
@property (nonatomic,assign) RootViewController *rootViewController;
@property (nonatomic,retain) UILabel *label;
@end
RootView.m
#import "RootView.h"
#import "RootViewController.h"
@implementation RootView
@synthesize rootViewController;
@synthesize label;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//Create the label
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100,100, 50)];
//Set the font bold
testLabel.font = [UIFont boldSystemFontOfSize:20.0];
//Set the backgroundcolor of the label to transparent
testLabel.backgroundColor = [UIColor clearColor];
//Set the text alignment of the text label to left
testLabel.textAlignment = UITextAlignmentLeft;
//Set the text color of the text label to black
testLabel.textColor = [UIColor blackColor];
testLabel.text = @"01:30";
self.label = testLabel;
[self addSubview:label];
[testLabel release];
}
return self;
}
- (void)dealloc
{
[label release];
rootViewController = nil;
[super dealloc];
}
@end
我更改了代码,但似乎无法正常工作.....
好的解决了我忘了这行“self.rootView = rootV;”
答案 0 :(得分:2)
在-initRootView方法返回之后,您的视图无法找到其控制器的内容,但您尝试在该方法中使用该控制器。
也就是说,如果你按照通常的Cocoa Touch模式创建视图的视图控制器会好得多。视图控制器应该懒惰地创建它们的视图,也就是说它们推迟视图创建和初始化,直到调用-loadView方法。您可以覆盖-loadView来创建视图,还可以覆盖-viewDidLoad来执行创建视图后需要完成的任何设置工作。
此外,通常不建议视图了解其控制器。控制器应该告诉视图要做什么,而不是相反。如果需要视图将一些信息发送到控制器,通常会将控制器作为视图的委托提供给视图。但是如果你只是需要视图控制器能够找到一些子视图,比如你的标签,那么在容器视图中为它提供一些访问器可能是个好主意(这样视图控制器就可以说{{1}另一个选项是将子视图的标记属性设置为某个唯一值,并让控制器使用它来查找子视图。
答案 1 :(得分:1)
问题很容易发现,但需要一些工作来解决。
查看代码,我立即想要建议的是将所有RootView初始化代码放在RootViewController的loadView
方法中。那应该是(see here why)。
另外,如果您绝对需要RootView在RootViewController上提供引用,那么您应该在viewDidLoad
中执行此操作。但我不建议这样做。
使用MVC模式时,控制器负责初始化和更新视图。应该从RootView的实现中删除行self.rootViewController.rootViewLabel = testLabel;
。目前还不清楚你的意图是什么,但如果你想更新rootViewLabel,你应该让控制器这样做。
总结一下:
// RootViewController.m
- (id)initRootViewController{
self = [super init];
if(self){
// other init code here
}
return self;
}
- (void)loadView {
RootView *rootV = [[RootView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
self.view = rootV;
[rootV release];
}
- (void)viewDidLoad {
[super viewDidLoad];
// etc...
}
// etc.
现在,对于RootView,它的外观如下:
<强> RootView.h 强>
#import <UIKit/UIKit.h>
@interface RootView : UIView {
UILabel *rootViewLabel;
}
// moved from RootViewController
@property (nonatomic, retain) UILabel *rootViewLabel;
@end
<强> RootView.m 强>
#import "RootView.h"
@implementation RootView
@synthesize rootViewLabel;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Whatever initialization code you might have
//Create the label
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100,100, 50)];
//Set the font bold
testLabel.font = [UIFont boldSystemFontOfSize:20.0];
//Set the backgroundcolor of the label to transparent
testLabel.backgroundColor = [UIColor clearColor];
//Set the text alignment of the text label to left
testLabel.textAlignment = UITextAlignmentLeft;
//Set the text color of the text label to black
testLabel.textColor = [UIColor blackColor];
testLabel.text = @"01:30";
self.rootViewLabel = testLabel;
[testLabel release];
// add rootViewLabel as a subview of your this view
[self addSubView:rootViewLabel];
}
return self;
}
- (void)dealloc
{
[rootViewLabel release];
[super dealloc];
}
@end
我希望这能让您了解如何构建视图初始化代码......
(免责声明,我现在无法测试此代码,请指出任何错误!谢谢)
答案 2 :(得分:0)
不确定为什么你这样做,但如果你将控制器传递给视图的init,你可能会使它工作:
RootView *rootV = [[RootView alloc] initRootView:self];
view的init:
- (id)initRootView:(UIViewController*)controller
{
self.rootViewController = controller;
self.rootViewController.rootViewLabel = testLabel;