使用来自多个视图控制器的自定义 UIView

Posted

技术标签:

【中文标题】使用来自多个视图控制器的自定义 UIView【英文标题】:Using a custom UIView from multiple view controllers 【发布时间】:2009-06-07 01:09:56 【问题描述】:

我创建了一个自定义 UIView,我想在我的 iPhone 应用程序中的多个不同视图控制器上使用它。目前,我已经从第一个视图控制器的 nib 文件中复制了包含控件的 UIView,将其粘贴到其他视图控制器中,然后将所有操作连接到每个视图控制器。这工作正常,但不是我想使用此自定义视图的最佳方式。

我的自定义视图相当简单,它由一些带有标签的 UIButtons 组成,点击这些按钮会触发更改我的视图控制器视图上控件内容的操作。

合并此 UIView 的定义和使用的策略是什么?理想情况下,我只想从视图控制器的 nib 中引用此自定义视图,并让我的视图控制器响应来自此自定义视图的操作。

编辑:好的,根据 J.Biard 的建议,我尝试了以下方法,但运气不佳。

我创建了另一个基于 UIView 的 nib 文件,其中包含可重用视图和 UIView 子类 .m 和 .h 文件的内容(现在只是一些 UIButton 对象),然后将 nib File's Owner 类设置为我新创建的类名。

然后,我添加了 J.Biard 的大部分代码(我将 rect 更改为 50,50,100,100,暂时省略了 setDelegate,因为我现在只是想让它在视觉上工作,我发现在应用启动时显示的第一个视图控制器的 viewDidLoad 方法结束时,[self.view addSubview:view] 比 [self addSubView:view] 工作得更好。

我现在得到的是我的主视图,其中有一个黑色方块。我是否错过了某个地方的插座,或者 UIView 子类中的 initWithFrame 或 drawRect 是否需要一些初始化?

【问题讨论】:

【参考方案1】:

创建您的 MyCustomView 类和 nib 文件。

在 nib 文件中,将 Files Owner 设置为 MyCustomView - 然后像平常一样使用*** UIView 设计您的视图。在 MyCustomView 中创建一个 IBOutlet 以链接到 nib 文件中的*** UIView。

在 MyCustomView 中添加这个方法:

- (BOOL) loadMyNibFile 
if (![[NSBundle mainBundle] loadNibNamed:@"MyCustomView" owner:self options:nil]) 
    return NO;

return YES;

在您的视图控制器中,您可以像这样使用此自定义视图

- (void)viewDidLoad 

MyCustomView *customView = [[MyCustomView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[customView loadMyNibFile];
[self.view addSubview:customView.view]; //customView.view is the IBOutlet you created
    [customView release];


如果您愿意,也可以在 MyCustomView 上创建一个方便的类方法来执行此操作。

【讨论】:

如果您想通过使用 Interface Builder 来完成这最后一部分(而不是在控制器中以编程方式设置 customView)怎么办?这可能吗?你会怎么做? 如果您想通过使用 Interface Builder 来完成这最后一部分(而不是在控制器中以编程方式设置 customView)怎么办?这可能吗?你会怎么做?【参考方案2】:

如果它非常简单,我建议您在代码中创建 UIView 的子类并创建此类的实例(或者您可以使用 Interface Builder 创建自定义 UIView,然后将其归档到 NIB 文件中并稍后恢复也使用代码)。

使用代码解决方案,您可以通过调用以下代码在控制器中创建自定义 UIView 的实例:

#import "MyCustomView.h"

// let the superview decide how big it should be or set it as needed.
CGRect sizeRect = CGRectMake(0,0,0,0);

// create an instance of your view   
MyCustomView *view = [MyCustomView alloc] initWithFrame:sizeRect];

// set a custom delegate on the view or set callback methods using @selector()...
[view setDelegate:self];  // self = view controller

// add the view to the controller somewhere... (eg: update CGRect above as needed)
[self addSubView:view];

// don't forget to release the view somewhere ;-)

本示例假设您创建了一个委托协议,您的视图控制器可以响应该委托协议,或者您可以使用 @selector 动态连接事件。如果您不想在代码中创建视图实例,您可以将“UIView”添加到您的 NIB 文件并在检查器窗口中设置它的类类型(命令 -> 4 -> 类下拉菜单)。

如果您想在界面生成器中完成所有操作,您可以创建自定义 UIView 并使用类似“- (NSArray *)loadNibNamed:(NSString *)name owner:(id)owner options:(NSDictionary *)options”(请参阅 NSBundle)动态加载 NIB 文件。这提出了它自己的挑战,尽管它也是可行的。

最复杂的选项是创建您自己的 xcode 自定义 UI 库/插件,以便您的自定义控件/视图可以像 Apple 提供的任何其他控件一样从库窗口拖到每个 NIB 文件中。

希望这可以为您澄清或消除一些重复使用控件的选项。

干杯-

【讨论】:

以上是关于使用来自多个视图控制器的自定义 UIView的主要内容,如果未能解决你的问题,请参考以下文章

我的自定义 UIView 没有收到触摸

在另一个视图控制器展开 segue 后重新加载 UIView 数据上的自定义 tableview

在视图控制器中使用自定义 uiview

iOS 自定义 .xib 视图按钮点击检测在视图控制器 (Swift)

故事板中的自定义 UIView

来自 Interface Builder 的自定义 UIView