Ios 如果您感到困惑,最佳做法是什么?
我对为自己的UIView子类创建XIB的大部分过程都很熟悉,但并不是每件事都能正常工作——这主要与IBOutlets连接有关。我可以让他们以一种迂回的方式工作 我的设置如下:Ios 如果您感到困惑,最佳做法是什么?,ios,uiview,init,iboutlet,loadnibnamed,Ios,Uiview,Init,Iboutlet,Loadnibnamed,我对为自己的UIView子类创建XIB的大部分过程都很熟悉,但并不是每件事都能正常工作——这主要与IBOutlets连接有关。我可以让他们以一种迂回的方式工作 我的设置如下: 我有MyClass.h和MyClass.m。它们有用于UIView(称为view)和UILabel(称为myLabel)的IBOutlet。我添加了“view”属性,因为一些在线示例似乎表明您需要它,它实际上解决了一个问题,即我遇到了崩溃,因为它找不到view属性,我想甚至在UIView父类中也找不到 我有一个名为MyC
- 我有MyClass.h和MyClass.m。它们有用于UIView(称为view)和UILabel(称为myLabel)的IBOutlet。我添加了“view”属性,因为一些在线示例似乎表明您需要它,它实际上解决了一个问题,即我遇到了崩溃,因为它找不到view属性,我想甚至在UIView父类中也找不到
- 我有一个名为MyClass.XIB的XIB文件,它的文件所有者自定义类是MyClass,在该类的my.h和.m存在之后正确地进行了预填充
self = [super init];
或者诸如此类的
我感觉到我在这里做错了,但是在线示例在init方法中也发生了类似的事情,但是他们将该子视图0分配给view属性,并将其作为子视图添加—但这不是总共两个MyClass实例吗?一个基本上未链接到IBOutlets,包含通过loadNibNamed实例化的子MyClass?或者充其量,它不是一个带有额外中介UIView的MyClass实例,其中包含我最初希望作为MyClass的直接子级的所有IBoutlet吗?在执行instanceOfMyClass.frame.size.width之类的操作时,这会带来一点麻烦,因为它返回0,而引入的子UIView返回的是我想要的真实帧大小
我做错的是在init方法中处理loadNibNamed吗?我应该做更多类似的事情吗
MyClass *instance = [[MyClass alloc] init];
[[NSBundle mainBundle] loadNibNamed:@"MyClass" owner:instance options:nil];
MyClass *instance = [[[NSBundle mainBundle] loadNibNamed:@"MyClass" owner:nil options:nil] objectAtIndex:0];
还是像这样
MyClass *instance = [[MyClass alloc] init];
[[NSBundle mainBundle] loadNibNamed:@"MyClass" owner:instance options:nil];
MyClass *instance = [[[NSBundle mainBundle] loadNibNamed:@"MyClass" owner:nil options:nil] objectAtIndex:0];
提前感谢您的帮助 第二个选项是正确的。您可以执行的最具防御性的代码如下:
+ (id)loadNibNamed:(NSString *)nibName ofClass:(Class)objClass {
if (nibName && objClass) {
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:nibName
owner:nil
options:nil];
for (id currentObject in objects ){
if ([currentObject isKindOfClass:objClass])
return currentObject;
}
}
return nil;
}
MyClass *myClassInstance = [Utility loadNibNamed:@"the_nib_name"
ofClass:[MyClass class]];
// In my case, the code is in a Utility class, you should
// put it wherever it fits best
这样称呼:
+ (id)loadNibNamed:(NSString *)nibName ofClass:(Class)objClass {
if (nibName && objClass) {
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:nibName
owner:nil
options:nil];
for (id currentObject in objects ){
if ([currentObject isKindOfClass:objClass])
return currentObject;
}
}
return nil;
}
MyClass *myClassInstance = [Utility loadNibNamed:@"the_nib_name"
ofClass:[MyClass class]];
// In my case, the code is in a Utility class, you should
// put it wherever it fits best
我假设您的MyClass是
UIView
的子类?如果是这种情况,那么您需要确保.xib的UIView
实际上是MyClass。这是在界面生成器右侧的第三个选项卡上定义的,在选择视图后,您需要做的就是通过loadNibNamed
创建子视图,设置框架,并将其添加到子视图中。例如,我使用myMyView
类添加了三个子视图,这是一个UIView
子类,其接口在NIB中定义,MyView.xib
:
因此,我为我的UIView
子类定义了initWithFrame
:
- (id)initWithFrame:(CGRect)frame
{
NSLog(@"%s", __FUNCTION__);
self = [super initWithFrame:frame];
if (self)
{
NSArray *nibContents =
[[NSBundle mainBundle] loadNibNamed:@"MyView"
owner:self
options:nil];
[self addSubview:nibContents[0]];
}
return self;
}
因此,例如,在我的UIViewController
中,我可以加载两个子类的UIView
对象,如下所示:
for (NSInteger i = 0; i < 3; i++)
{
CGRect frame = CGRectMake(0.0, i * 100.0 + 75.0, 320.0, 100.0);
MyView *myView = [[MyView alloc] initWithFrame:frame];
[self.view addSubview:myView];
// if you want, do something with it:
// Here I'm initializing a text field and label
myView.textField.text = [NSString stringWithFormat:@"MyView textfield #%d",
i + 1];
myView.label.text = [NSString stringWithFormat:@"MyView label #%d",
i + 1];
}
NIB文件,
MyClass.xib
,可以指定UIView
的基类,如果您愿意,其中包含所有与视图相关的代码(例如,假设MyClass是UIView
的子类)。我使用了一种方法:
UIView
创建一个子类,该子类将被称为MyClass
ParentViewController
MyClass
MyClass
中声明的任何出口/操作都将
通过从视图(不是文件的所有者)中单击并拖动连接。如果要将它们连接到来自ParentViewController
的变量,请单击“从文件所有者拖动”ParentViewController
中,您需要声明一个实例
MyClass
的变量ParentViewController.h
添加以下内容:
@class MyClass
@interface ParentViewController : UIViewController {
MyClass *myClass;
}
@property (strong, nonatomic) MyClass *myClass;
在您的实现中综合这一点,并在您的实现中添加以下内容
viewDidLoad
方法:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSBundle mainBundle] loadNibNamed:@"MyClass" owner:self options:nil];
self.myClass.frame = CGRectMake(X,Y,W,H); //put your values in.
[self.view addSubview:self.myClass];
}
在某一点上,您说您正在创建一个UIView子类,然后编写关于在其中包含IBoutlet以连接到视图和标签的内容。这很不寻常。通常,您创建一个视图控制器,并为其提供要管理的视图,无论是库存视图还是自定义视图。第一个示例确实创建了两个
MyClass
实例,这可能不是您想要的。不幸的是,我不知道这里有什么建议,因为您对MyClass
的使用不清楚。您打算如何使用MyClass
?具体来说,您在做什么时看到“由于找不到view属性而崩溃”?这让我怀疑您对这里的视图和控制器有些混淆。谢谢。我之所以避免使用控制器,是因为本质上我是在一对多关系中从子类构建一个相当复杂的UI,因此我将MyClass视为一个被复制多次的视图。由于除了一次填充它们之外,我对它们没有做太多的处理,所以我认为最好将它们作为一个数组,并从一个父级“控制器”(即ViewController)填充它们。再次感谢!在您使用MyView*MyView=[[MyView alloc]initWithFrame:frame]的示例中,是否会使用XIB文件自动构造?您使用[[NSBundle mainBundle]loadNibNamed:@“MyView”所有者:self options:nil]的第一个示例可能适合我,只要(a)我可以将其键入MyView并在将其添加为子视图之前使用它,以及(b)通过loadNibNamed构造,它将调用我无法覆盖的init方法