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

将自定义 UIView 锚定到相对于屏幕大小的屏幕底部

将自定义视图动态添加到 iOS 中的每个视图控制器

如何将自定义视图拖动为 Xcode 6 中自定义视图的私有属性

如何将自定义 UIControl 中按下的 UIButton 传递给我的视图控制器?

将自定义 UIView 添加到 TableViewCell