ios UIView 和 initWithFrame 和一个 NIB 文件。如何加载 NIB 文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5056219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:57:40  来源:igfitidea点击:

UIView and initWithFrame and a NIB file. How can i get the NIB file loaded?

iosobjective-c

提问by dbrasco

I have a UIViewcalled baseViewand in that i have initWithFramewhere i add some other views and do some custom stuff. The same view also has a NIB file.

我有一个UIView电话baseView,在initWithFrame那里我可以添加一些其他视图并执行一些自定义操作。同一个视图还有一个 NIB 文件。

Now i have a UIViewControllerclass named AppControllerin which i want to add the baseViewview to the view of the AppControllerview so i am doing this :

现在我有一个UIViewController名为的类AppController,我想将baseView视图添加到视图的视图中,AppController所以我这样做:

self.view = baseView;but the problem is that the NIB file does not get loaded. How do i make sure the customized stuff AND the NIB file get′s loaded/run ?

self.view = baseView;但问题是未加载 NIB 文件。我如何确保自定义的东西和 NIB 文件被加载/运行?

回答by Bogatyr

You have many options, depending on how your "baseView" class is meant to be used and integrated in to your application. It's not clear just how you intend to use this class -- as the view in a UIViewController subclass, or as a reusable modular component mean to be instantiated multiple times throughout your application, for use in many different view controllers.

您有很多选择,具体取决于您的“baseView”类将如何使用和集成到您的应用程序中。不清楚您打算如何使用这个类——作为 UIViewController 子类中的视图,或者作为可重用的模块化组件意味着在整个应用程序中多次实例化,以用于许多不同的视图控制器。

If your view is meant to be the only view in a UIViewController subclass, then Phonitive is correct -- bundle it together with the UIViewController subclass .xib file and use the UIViewController's viewDidLoad to do final initialization.

如果您的视图是 UIViewController 子类中的唯一视图,那么 Phonitive 是正确的——将它与 UIViewController 子类 .xib 文件捆绑在一起,并使用 UIViewController 的 viewDidLoad 进行最终初始化。

But if you want your View class to be a subcomponent reused multiple times in different view controllers, integrated either via code or via inclusion in a .xib file for another controller, then you need to implement both the initWithFrame: init method, and awakeFromNib, to handle both cases. If your internal initialization always includes some objects from .xib, then in your initWithFrame you'll need to load your .xib manually in order to support "customer" classes that want to create your widget via code. And likewise, if a .xib file contains your object then you'll need to make sure you call any code-required finalization from awakeFromNib.

但是,如果您希望您的 View 类成为在不同视图控制器中多次重用的子组件,通过代码或通过包含在另一个控制器的 .xib 文件中进行集成,那么您需要同时实现 initWithFrame: init 方法和awakeFromNib,处理这两种情况。如果您的内部初始化总是包含一些来自 .xib 的对象,那么在您的 initWithFrame 中,您需要手动加载您的 .xib 以支持想要通过代码创建小部件的“客户”类。同样,如果 .xib 文件包含您的对象,那么您需要确保从awakeFromNib 调用任何需要代码的终结。

Here's an example of how to create a UIView subclass component with the UI design in a nib.

下面是一个示例,说明如何使用 nib 中的 UI 设计创建 UIView 子类组件。

MyView.h:

我的视图.h:

@interface MyView : UIView
{
    UIView *view;
    UILabel *l;
}
@property (nonatomic, retain) IBOutlet UIView *view;
@property (nonatomic, retain) IBOutlet UILabel *l;

MyView.m:

我的视图.m:

#import "MyView.h"
@implementation MyView
@synthesize l, view;

- (id)initWithFrame:(CGRect)frame 
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        // Initialization code.
        //
        [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil];
        [self addSubview:self.view];
    }
    return self;
}

- (void) awakeFromNib
{
    [super awakeFromNib];

    // commenters report the next line causes infinite recursion, so removing it
    // [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil];
    [self addSubview:self.view];
}

- (void) dealloc
{
     [l release];
     [view release];
     [super dealloc];
}

Here's what the nib file looks like (except that file's owner needs to be changed to MyView class).

这是 nib 文件的样子(除了该文件的所有者需要更改为 MyView 类)。

enter image description here

在此处输入图片说明

be sure to hook up both the view and label outlets to File's Owner. That's it! A template for creating re-usable UIView widgets.

确保将视图和标签出口连接到文件所有者。就是这样!用于创建可重用 UIView 小部件的模板。

The really neat thing about this structure is that you can place instances of your MyView object in other nib files, just place a UIView at the location/size you want, then change the class in the identity inspector (CMD-4) to MyView, and boom, you've got an instance of your widget in whatever views you want! Just like UIKit objects you can implement delegate protocols so that objects using your widget can be notified of interesting events, and can provide data to display in the widget to customize it.

这种结构的真正巧妙之处在于,您可以将 MyView 对象的实例放置在其他 nib 文件中,只需将 UIView 放置在您想要的位置/大小,然后将身份检查器 (CMD-4) 中的类更改为 MyView,和繁荣,你有你想要的任何视图的小部件实例!就像 UIKit 对象一样,您可以实现委托协议,以便使用您的小部件的对象可以收到有趣事件的通知,并且可以提供数据以显示在小部件中以对其进行自定义。

回答by crissag

I found this post after having a problem trying to do this in my app. I was trying to instantiate the view from a NIB in the ViewDidLoad method, but the controls acted as if they were disabled. I struggled with this trying to directly set the userInteractionEnabled property and programmatically set the touch event selector for a button in this view. Nothing worked. I stumbled upon another post and discovered that viewDidLoad was probably too soon to be loading this NIB. I moved the load to the ViewWillAppear method and everything worked. Hope this helps someone else struggling with this. The main response was great and works well for me now that I have it being called from the proper place.

我在尝试在我的应用程序中执行此操作时遇到问题后发现了这篇文章。我试图在 ViewDidLoad 方法中从 NIB 实例化视图,但控件的行为就像它们被禁用一样。我在尝试直接设置 userInteractionEnabled 属性并以编程方式为此视图中的按钮设置触摸事件选择器时遇到了困难。没有任何效果。我偶然发现了另一篇文章,发现 viewDidLoad 加载这个 NIB 可能还为时过早。我将负载移至 ViewWillAppear 方法,一切正常。希望这可以帮助其他人为此苦苦挣扎。主要反应很好,现在对我来说效果很好,因为我从正确的地方调用了它。

回答by Phonitive

if you want to use a NIB, it's better for your UIView to be linked with a UIViewController, in this case you can use

如果您想使用 NIB,最好将您的 UIView 与 UIViewController 链接,在这种情况下,您可以使用

UIViewController *vc=[[UIViewController alloc] initWithNibName:@"YourNIBWihtOUTEXTENSION" bundle:nil]

[self.view addSubView:vc.view ];

becareful of memory leaks, you have to release vc

小心内存泄漏,你必须释放vc

回答by felixwcf

If you have a custom UIView with a xib file.

如果您有一个带有 xib 文件的自定义 UIView。

- (id)initWithFrame:(CGRect)frame
{
   self = [super initWithFrame:frame];

   id mainView;
   if (self)
   {
       NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"HomeAllAdsView" owner:self options:nil];
       mainView = [subviewArray objectAtIndex:0];    
   }
   return mainView;
}

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

回答by Maria

This post helped me Building Reusable Views With Interface Builder and Auto Layout. The trick had to do with setting the IBOutlets to the FileOwner and then adding the content view to itself after loading the nib

这篇文章帮助我使用 Interface Builder 和 Auto Layout 构建可重用视图。诀窍是将 IBOutlets 设置为 FileOwner,然后在加载笔尖后将内容视图添加到自身