ObjC开发:如何从其他类访问某类内定义的IBOutlet类型id属性
问题解答
你现在直接alloc init控制器拿不到IBOutlet的核心原因:IBOutlet是和xib/Storyboard的界面元素绑定的,直接alloc init创建的控制器实例不会加载对应的界面文件,所有IBOutlet属性默认都是空值,自然没法访问。
1. 先把IBOutlet属性在控制器的头文件(.h)中公开声明
要让其他类能访问控制器的属性,属性不能定义在.m的类扩展里,必须放在.h的公开接口中,示例:
// MyController.h #import <Cocoa/Cocoa.h> @interface MyController : NSViewController // 替换成你自己的IBOutlet属性名和对应的视图类 @property (nonatomic, weak) IBOutlet NSView *targetExportView; @end
2. 正确获取控制器实例,不要直接用alloc init
根据你的控制器来源选择正确的初始化/获取方式:
- 如果控制器是xib创建的:使用
initWithNibName:bundle:初始化,完成后主动触发视图加载,IBOutlet才会被赋值MyController *saveTextViewController = [[MyController alloc] initWithNibName:@"MyController" bundle:nil]; // 主动加载视图,触发IBOutlet关联 [saveTextViewController view]; - 如果控制器是Storyboard创建的:使用Storyboard的
instantiateViewControllerWithIdentifier:方法获取实例 - 如果你要获取已经显示在界面上的控制器实例:不要新建实例,直接通过控制器层级拿到已经存在的对象,否则你导出的PDF内容和当前界面显示的不一致。比如从父控制器、窗口根控制器路径获取对应实例。
3. 访问属性调用对应方法
拿到有效控制器实例后,直接调用公开的IBOutlet属性即可:
NSRect exportBounds = saveTextViewController.targetExportView.bounds; NSData *pdfData = [saveTextViewController.targetExportView dataWithPDFInsideRect:exportBounds];
优化建议
可以不用把整个控制器实例传给绘图类,直接给绘图类加一个NSView类型的参数,初始化或者调用绘图方法的时候把目标视图传进去,耦合度更低,也不用依赖控制器层。
内容的提问来源于stack exchange,提问作者GeraldTheGerm
相关产品推荐
相关产品推荐

