Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/93.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如果您感到困惑,最佳做法是什么?_Ios_Uiview_Init_Iboutlet_Loadnibnamed - Fatal编程技术网

Ios 如果您感到困惑,最佳做法是什么?

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

我对为自己的UIView子类创建XIB的大部分过程都很熟悉,但并不是每件事都能正常工作——这主要与IBOutlets连接有关。我可以让他们以一种迂回的方式工作

我的设置如下:

  • 我有MyClass.h和MyClass.m。它们有用于UIView(称为view)和UILabel(称为myLabel)的IBOutlet。我添加了“view”属性,因为一些在线示例似乎表明您需要它,它实际上解决了一个问题,即我遇到了崩溃,因为它找不到view属性,我想甚至在UIView父类中也找不到
  • 我有一个名为MyClass.XIB的XIB文件,它的文件所有者自定义类是MyClass,在该类的my.h和.m存在之后正确地进行了预填充
我的init方法就是我遇到问题的地方

我尝试使用NSBundle mainBundle的'loadNibNamed'方法,并将所有者设置为'self',希望我正在创建视图的一个实例,并且它会自动将其输出与我的类中的输出匹配(我知道如何做,我对此很小心)。然后我想我应该使“self”与该nib中索引0处的子视图相等,而不是这样做

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
创建子视图,设置框架,并将其添加到子视图中。例如,我使用my
MyView
类添加了三个子视图,这是一个
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
  • 创建一个视图xib文件。在界面生成器中打开, 单击文件的所有者,然后在标识检查器中更改类 到父视图控制器的视图,例如。
    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方法