iOS - 将自定义 UIView 放在视图控制器中
Posted
技术标签:
【中文标题】iOS - 将自定义 UIView 放在视图控制器中【英文标题】:iOS - put custom UIView in a View Controller 【发布时间】:2013-02-16 15:29:21 【问题描述】:我的 ios 应用有一个根视图控制器,我想在运行时向它添加一些自定义 UIView
。我称这些自定义视图小部件是因为它们很小并且除了大小、标签文本等基本相同。
我为我的小部件创建了 .h 和 .m 以及 .xib 文件。在我的根视图控制器viewDidLoad
我这样做:
TestMyView *cell = [[[NSBundle mainBundle] loadNibNamed:@"TestMyView" owner:self options:nil] objectAtIndex:0];
[self.view addSubview: cell];
它工作正常。但是,我还是想不通:
如果我将UILabel
mylabel 作为 IBOutlet 添加到我的自定义 UIView 类 .h 文件中,为什么会出现异常 "[<TestViewController 0x7517210> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key mylabel"
。 (我将 UILabel 拖放到 IB 中,然后控制拖动到 .h)创建视图时我需要更改标签文本。而且我不太明白为什么它抱怨 TestViewController 而我没有向它添加 IBOutlet,而是我的自定义视图 .h 类?
那我该如何以正确的方式更改标签文本。我不想为我的小部件创建视图控制器,因为我认为没有必要。我需要创建 5-6 个小部件,所以我需要为它们创建 5-6 个视图控制器?
当我创建小部件时似乎没有调用 initWithCoder?我看到苹果文档库说如果从 nib 文件加载视图,这个方法会被调用。
如果您认为我解释这一点很烂,这是我的项目代码: https://dl.dropbox.com/u/43017476/custom.tar.gz
【问题讨论】:
【参考方案1】:你已经接近了。一些笔记。
1st - 当您从 nip 加载视图时,“所有者”是具有 nib 引用的属性 (IBOutlets) 的类。那可能是TestMyView 的一个实例。通常,创建自定义视图并让它加载它自己的 nib(如下图所示)。
2nd - loadNibNamed 返回 NSARRAY,而不是 UIVIEW;所以你会想把你的视图拉出数组。
以下是创建自定义视图(小部件)的示例:
CGRect frame = CGRectMake(nextLeft, nextTop, tileWidth, tileHeight);
TestMyView *widget = [[TestMyView alloc] initWithFrame:frame andFoo:foo];
[widget setWidgetTappedBlock:^
// handle tap for this widget
];
[self.widgetContainerView addSubview:widget];
这是您的自定义视图实现的一部分:
@implementation TestMyView
- (id)initWithFrame:(CGRect)frame andFoo:(Foo *)foo
self = [super initWithFrame:frame];
if (self)
[self setBackgroundColor:[UIColor clearColor]];
NSArray *nibObjects=[[NSBundle mainBundle] loadNibNamed:@"TestMyView" owner:self options:nil];
[self addSubview:[nibObjects objectAtIndex:0]];
// More initialization code
return self;
@end
还有界面:
@interface ProductTileView : UIView
@property (nonatomic, weak) IBOutlet UIView *view;
@property (nonatomic, copy) ProductTappedBlock widgetTappedBlock;
- (id)initWithFrame:(CGRect)frame andFoo:(Foo *)foo;
@end
编辑: PS在你的例子中,错误是因为发送给loadNib的所有者是'self',这是你的视图控制器。您的视图控制器没有“myLabel”属性,但您的自定义视图却有。
【讨论】:
第 1 点是正确的,这可能是个问题。但对于第二个,我有一个问题。当我们在xib中创建视图时,为什么还要在代码中重新设置一个框架呢?而且当我们从 nsbundle 数组视图中提取视图时,我认为我们需要输入 cast。 +1 您可以在 IB 中创建一个视图并将您的自定义类分配给它。但是,@Lukas 正在动态创建“小部件”视图,并且几乎肯定会以编程方式将它们放置在屏幕上。在其他情况下,您可能不需要设置框架。 NSArray 保存 NSObjects; UIView 是一个 NSObject(子类)。我不相信缺少演员表会产生警告或降低可读性,但肯定不会伤害任何东西。 我不知道你所说的 ios 中的小部件视图是什么意思。 问题的作者将他的自定义视图称为“小部件”,仅此而已。答案是为他量身定做的。其他人可以根据自己的需要进行调整。 @R.A 他的意思是在我的问题中我将自定义 UIVIEW 称为“小部件”。不是 ios 或 xcode 中的术语。【参考方案2】:我认为您必须先启动它们才能添加到您的 rootView!
TestMyView *cell = [[TestMyView alloc]initWithNibName:@"TestMyView" bundle:[NSBundle mainBundle]];
[self.view addSubview: cell];
【讨论】:
感谢您的回答,但 TestMyView 是 UIView 的子类,而不是 UIViewController,所以 initWithNibName 不适合它..以上是关于iOS - 将自定义 UIView 放在视图控制器中的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式将自定义 uiview 添加到视图控制器 SWIFT
如何将自定义视图拖动为 Xcode 6 中自定义视图的私有属性