将在xib中创建的自定义子视图添加到视图控制器的视图中 - 我做错了什么

62

我在一个xib文件中创建了一个视图(包含活动指示器、进度条和标签)。然后我创建了.h/.m文件:

#import <UIKit/UIKit.h>

@interface MyCustomView : UIView {
    IBOutlet UIActivityIndicatorView *actIndicator;
    IBOutlet UIProgressView *progressBar;
    IBOutlet UILabel *statusMsg;
}

@end

#import "MyCustomView.h"

@implementation MyCustomView    

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        // Initialization code
    }
    return self;
}

- (void)dealloc {
    [super dealloc];
}

@end

在 IB 中,我将文件所有者和视图身份设置为 MyCustomView,并将 IBOutlet 连接到文件的所有者

在 MyViewController.m 中,我已经:

- (void)viewDidLoad {

    [super viewDidLoad];   

    UIView *subView = [[MyCustomView alloc] initWithFrame:myTableView.frame];
    [subView setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5]];

    [myTableView addSubview:subView];
    [subView release];
}
当我运行应用程序时,视图被添加了,但是无法看到标签、进度条和活动指示器。我做错了什么?
3个回答

131
你需要使用 -loadNibNamed 方法来加载它。-initWithNibName 只适用于 UIViewControllers。
将以下代码添加到你的 MyCustomView 的初始化方法中:
NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"MyCustomView" owner:self options:nil];
UIView *mainView = [subviewArray objectAtIndex:0];
[self addSubview:mainView];
记住,如果你从nib初始化一个对象,它会调用- (id)initWithCoder:(NSCoder *)aDecoder进行初始化,因此如果你在nib中创建MyCustomView对象,需要重写该方法。如果你只是使用initWithFrame:,那么只需覆盖该方法并添加上述代码即可。另外,在你的nib中,请确保有一个顶层UIView,并将所有其他元素放置其中(这可以确保你的子视图数组只有一个条目)。
这将从nib加载视图并将它们添加到对象中,应该能解决问题。

我在initWithFrame中使用了你的代码,现在我可以看到MyCustomView及其所有元素,但有一件事情不起作用。在MyViewController的viewDidLoad中,我有以下代码: UIView *subView = [[MyCustomView alloc] initWithFrame:myTableView.frame]; [subView setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5]]; [myTableView addSubview:subView]; [subView release]; 这样我应该能看到它下面的表格。有什么想法吗? - Sefran2
如果我在initWithFrame中设置它,它就可以工作。现在我需要了解如何支持此视图的横向模式 :) 谢谢 - Sefran2
我找到了另一种解决方案,也解决了横向问题。我在MyViewController中使用loadNibNamed代码(当我需要显示子视图时),并将任何其他自定义放在MyCustomView.m的awakeFromNib方法中。 - Sefran2
嘿,方法[self addSubview:mainView]只会将你在IB中创建的视图添加到MyCustomView中。我尝试了你的方法,然后尝试为MyCustomView设置框架。结果发现框架确实改变了,但是.xib中创建的视图的框架并没有改变。我该如何通过MyCustomView更改IB视图的框架? - HG's
@Ned 感谢您关于 initWithCoder: 的提示。我无法弄清楚我的自定义视图是如何创建的,没有调用 initinitWithFrame - Christopher Pickslay
显示剩余2条评论

1

我认为你需要使用这个方法:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;

这是因为您需要在“nibNameOrNil”中传递.xib文件名。

在IB中指定文件所有者和视图为MyCustomView应该不够了吗? - Sefran2
如果我使用initWithNibName,我会得到警告:'UIView' 可能无法响应 '-initWithNibName:bundle:'。 - Sefran2

0

正如hocker所说,您必须使用该方法传递XIB名称(不带扩展名)。

然后,您必须控制此列表:

  • 在IB中打开.xib文件
  • 单击文件所有者并选择正确的类(在您的情况下为MyCustomView)
  • 按住Control键并从文件所有者拖动到视图(现在视图的输出已经准备好了)

希望它能起作用。干杯。


如果文件所有者是MyCustomView,我就不能从文件所有者拖动到视图。所以我把文件所有者设置为MyViewController,将视图设置为MyCustomView,然后从视图拖动到IBOutlets,但它不起作用。 - Sefran2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接