自定义 SCNView 的初始化方法

init method for custom SCNView

我创建了一个继承自 SCNView 的自定义 class "CustomSCNView"。我想在另一个视图控制器中使用自定义 class。所以我需要创建一个 CustomSCNView 对象并使用它来对另一个 class 进行操作。但是如何在另一个 class 中创建 CustomSCNView 对象。 这不起作用:

CustomSCNView *customView = [[CustomSCNView alloc]init]; //in viewcontroller.m

抱歉忘记提及我使用界面生成器将 SCNView 拖到视图控制器,然后将其 class 设置为 CustomSCNView。

如果您查看 SCNViewdocumentation,它会告诉您:

You can create a SceneKit view by using its initWithFrame:options: method or by adding it to a nib file or storyboard.

所以你不能使用init方法,除非你已经实现你的[CustomSCNView init]方法来调用[super initWithFrame:options:]

如果您需要从 Interface Builder 访问自定义子类属性,请将这些属性标记为 IBInspectable(并可能实施 IBDesignable)。那是 documented by Apple here, and nicely summarized on NSHipster.

在任何初始化路径中,都必须调用超类的指定初始化器。对于 SCNView,这似乎是 initWithFrame:options:(没有这样记录,但 header 强烈暗示它)。看到这个 document on multiple initializers and subclassing.

尽管如此,子类化 SCNView 是一种代码味道,您可能会与框架作斗争并且工作过于努力。

我对你的问题有点困惑,但我在 https://github.com/NSGod/CustomSCNView 创建了一个示例项目,它可以满足你的需求。

首先,故事板在 ViewController 的视图中并排放置了 2 个 CustomSCNView。像你一样,我从 IB 调色板拖了 2 SCNViews 到视图,然后将自定义 class 设置为 CustomSCNView.

其次是CustomSCNViewclass,其定义如下:

#import <Cocoa/Cocoa.h>
#import <SceneKit/SceneKit.h>

@interface CustomSCNView : SCNView

@property (nonatomic, assign) BOOL allowsRotation;

@end

你可以看到,它有一个 allowsRotation 属性 任何其他对象都可以设置。

要为 allowsRotation 设置默认值,而不是 NO,您可以覆盖 initWithCoder:,这是您在 Interface Builder 中设置视图时使用的值,就像您所做的那样:

#import "CustomSCNView.h"

@implementation CustomSCNView

- (id)initWithCoder:(NSCoder *)coder {
    if ((self = [super initWithCoder:coder])) {
        _allowsRotation = YES;
    }
    return self;
}
@end

然后 ViewController 有 2 IBOutlet 到两个 CustomSCNView

#import <Cocoa/Cocoa.h>
#import <SceneKit/SceneKit.h>

@class CustomSCNView;

@interface ViewController : NSViewController

@property (weak) IBOutlet CustomSCNView *sView1;
@property (weak) IBOutlet CustomSCNView *sView2;

@end

ViewController.m:

#import "ViewController.h"
#import "CustomSCNView.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _sView1.allowsRotation = NO;
    _sView2.allowsRotation = YES;
}

@end

你可以看到在viewDidLoad中,你可以将两个视图的allowsRotation 属性设置成任何你想要的。当您 运行 此应用程序时,当加载 storyboard/nib 文件时,会自动为您创建 2 个 CustomSCNView 实例(通过 initWithCoder:)。无需创建 CustomSCNView 的另一个实例即可设置您已有的 2 个现有实例的属性。