在使用XCode 4.3.3的简单“单一视图”测试项目中:
我将UIView子类化,并在storyboard的Property Inspector中将其指定为要用作viewController默认视图的类。
在我的自定义UIView类TestUIView
中,我定义了一个名为“drawSwitch”的属性。
我在viewController类中导入自定义类的标题。
当尝试编译项目时,我很惊讶编译器不能使用下面的代码行识别我的子类,给出错误:属性'drawSwitch'在'UIView'类型的对象上找不到。这看起来很奇怪,因为我的自定义类TestUIView
被指示为viewController view
出口的类(如下图所示)。
[self.view setDrawSwitch:2];
然而,如果我投了它,代码编译并运行良好:
[(TestUIView*) self.view setDrawSwitch:2];
当我查看viewController的属性时,我的自定义类被指示为view属性的Outlet。
所以我对这里的故事板发生了什么感到困惑。
storyboard / XCode让我做一些编译器不满意的事情,只是一个GUI漏洞吗?
我知道我可以为我的自定义视图创建一个IBOutlet(下面是“testView”),但在view
插座已经定义的情况下创建一个额外的插座似乎是多余的。
我在这里遗漏了什么吗? (超出“它的工作方式”,可能就是这种情况)。
答案 0 :(得分:2)
编译器对故事板中设置的内容一无所知。它只知道视图控制器的.view
属性将是UIView。这样可以正常工作,因为您可以在运行时将任何UIView的子类分配给此属性而不会出现问题。
当您尝试使用view属性时,就会出现问题,就好像它是一个更具体的子类。编译器在运行时不知道它认为UIView实际上是一个不同的类。
你的“冗余”插座实际上就是Apple用UITableViewController实现这种情况的方式。 UITableViewController有一个.view
和一个.tableView
属性,它们都指向完全相同的对象 - 表视图。
另一种方法是覆盖属性以使其具有不同的类,如here和here所述,但这可能会对视图控制器产生不可预见的影响。我建议坚持使用一个更具体的类的单独属性 - 它肯定会使你的代码更具可读性。
偏离主题 - 这是我在Stack Overflow上的第1000个答案 - 欢迎你!
答案 1 :(得分:0)
有些东西你可能没有发布但是错了或者我可能没理解这个问题。
我尝试的一个简单示例可以通过故事板进行操作,不需要强制转换和简单使用。
所以这是SVTView.h的代码:
@interface SVTView : UIView{
}
-(void)sampleSet:(int)value;
@end
和SVTView.m:
#import "SVTView.h"
@implementation SVTView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
-(void)sampleSet:(int)value{
NSLog(@"setting value %d",value);
}
@end
最后在ViewController中使用:
#import <UIKit/UIKit.h>
#import "SVTView.h"
@interface SVTViewController : UIViewController{
IBOutlet SVTView * testView;
}
@property(nonatomic, retain) SVTView * testView;
@end
和Viewcontroller.m:
#import "SVTViewController.h"
@interface SVTViewController ()
@end
@implementation SVTViewController
@synthesize testView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[testView sampleSet:2];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
@end
引用Outlet已通过Storyboard连接,因此使用了实例变量。日志控制台显示了disred结果:
2012-07-28 07:51:02.227 SingleViewTest[1490:f803] setting value 2
Imo使用正确的类并不是多余的,冗余部分可能是类强制转换。