子类UIView,当设置为默认视图在故事板中时,编译器无法在不进行强制转换的情况下识别

时间:2012-07-28 05:24:58

标签: ios uiview uiviewcontroller storyboard

在使用XCode 4.3.3的简单“单一视图”测试项目中:

  1. 我将UIView子类化,并在storyboard的Property Inspector中将其指定为要用作viewController默认视图的类。

  2. 在我的自定义UIView类TestUIView中,我定义了一个名为“drawSwitch”的属性。

  3. 我在viewController类中导入自定义类的标题。

  4. 当尝试编译项目时,我很惊讶编译器不能使用下面的代码行识别我的子类,给出错误:属性'drawSwitch'在'UIView'类型的对象上找不到。这看起来很奇怪,因为我的自定义类TestUIView被指示为viewController view出口的类(如下图所示)。

    [self.view setDrawSwitch:2];
    

    然而,如果我投了它,代码编译并运行良好:

    [(TestUIView*) self.view setDrawSwitch:2];
    

    当我查看viewController的属性时,我的自定义类被指示为view属性的Outlet。

    所以我对这里的故事板发生了什么感到困惑。

    • storyboard / XCode让我做一些编译器不满意的事情,只是一个GUI漏洞吗?

    • 我知道我可以为我的自定义视图创建一个IBOutlet(下面是“testView”),但在view插座已经定义的情况下创建一个额外的插座似乎是多余的。

    我在这里遗漏了什么吗? (超出“它的工作方式”,可能就是这种情况)。

    enter image description here

2 个答案:

答案 0 :(得分:2)

编译器对故事板中设置的内容一无所知。它只知道视图控制器的.view属性将是UIView。这样可以正常工作,因为您可以在运行时将任何UIView的子类分配给此属性而不会出现问题。

当您尝试使用view属性时,就会出现问题,就好像它是一个更具体的子类。编译器在运行时不知道它认为UIView实际上是一个不同的类。

你的“冗余”插座实际上就是Apple用UITableViewController实现这种情况的方式。 UITableViewController有一个.view和一个.tableView属性,它们都指向完全相同的对象 - 表视图。

另一种方法是覆盖属性以使其具有不同的类,如herehere所述,但这可能会对视图控制器产生不可预见的影响。我建议坚持使用一个更具体的类的单独属性 - 它肯定会使你的代码更具可读性。

偏离主题 - 这是我在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使用正确的类并不是多余的,冗余部分可能是类强制转换。