自定义 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。
如果您查看 SCNView
的 documentation,它会告诉您:
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 SCNView
s 到视图,然后将自定义 class 设置为 CustomSCNView
.
其次是CustomSCNView
class,其定义如下:
#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 个现有实例的属性。
我创建了一个继承自 SCNView 的自定义 class "CustomSCNView"。我想在另一个视图控制器中使用自定义 class。所以我需要创建一个 CustomSCNView 对象并使用它来对另一个 class 进行操作。但是如何在另一个 class 中创建 CustomSCNView 对象。 这不起作用:
CustomSCNView *customView = [[CustomSCNView alloc]init]; //in viewcontroller.m
抱歉忘记提及我使用界面生成器将 SCNView 拖到视图控制器,然后将其 class 设置为 CustomSCNView。
如果您查看 SCNView
的 documentation,它会告诉您:
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 SCNView
s 到视图,然后将自定义 class 设置为 CustomSCNView
.
其次是CustomSCNView
class,其定义如下:
#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 个现有实例的属性。