【问题标题】:How to add an UIView from a XIB file as a subview to another Xib file如何将 XIB 文件中的 UIView 作为子视图添加到另一个 Xib 文件
【发布时间】:2015-06-20 05:53:51
【问题描述】:

我正在尝试将我在 XIB 中创建的自定义 UIView 添加到我的 main.storyboard 中的视图控制器中作为子视图。我该怎么做?

matchScrollView(标签 1)是 main.storyboard 中视图控制器中的 UIScrollView,而 matchView(标签 2)是我在另一个 XIB 文件中创建的自定义 UIView

按一下按钮,我想将自定义 UIView 添加到 UIScrollView 作为子视图。但我怎样才能真正让它出现在显示器上呢?我想我还没有分配和初始化它,以及指示位置等,但我该怎么做呢?我尝试了不同的方法但没有成功。我可以通过编程方式创建UIViews,但还没有找到从XIB 加载UIView 的方法。

-(IBAction) buttonTapped:(id)sender {

    UIScrollView *matchScrollView = (UIScrollView *) [self.view viewWithTag:1];
    UIView *matchView = (UIView *) [self.view viewWithTag:2];
    [matchScrollView addSubview:matchView];

}

我在另一个 XIB 文件中创建自定义 UIView 而不是直接在我的 main.storyboard 视图控制器上实现它的原因是因为我想多次重复使用同一个视图。所以UIScrollView 有很多UIViews 的子视图。

我希望我可以创建大量 MatchView 实例并将它们全部添加到 matchScrollView 作为子视图。

【问题讨论】:

    标签: ios objective-c xcode uiview xib


    【解决方案1】:

    您遇到的问题是完全正常的。 Apple 的设计方式不允许将自定义视图与他们自己的 xib 重用到其他 xib 中。

    假设您有一个名为 HeaderView 的自定义视图和一个名为 HeaderView.xib 的自定义 xib。假设您希望能够在另一个名为 GlobalView.xib 的 xib 中拖动子视图并将其类指定为 HeaderView 类型,期望它从 HeaderView.xib 加载该视图并将其插入到位。你可以这样做:

    A) 确保 HeaderView.xib 中的 File's Owner 设置为 HeaderView 类。

    B) 转到您的 GlobalView.xib,拖动子视图并使其成为 HeaderView 类。

    C) 在 HeaverView.m 中实现 initWithCoder,如果在加载视图后没有子视图意味着它是从 GlobalView 加载的,则从正确的 nib 手动加载它,连接 IBOutlets 并设置框架和自动调整掩码(如果需要)使用 GlobalView 的框架(这通常是你想要的)。

    - (id)initWithCoder:(NSCoder *)aDecoder {
        self = [super initWithCoder:aDecoder];
        if (self.subviews.count == 0) { //means view got loaded from GlobalView.xib or other external nib, cause there aren't any subviews
            HeaverView *viewFromNib = [[NSBundle mainBundle] loadNibNamed:@"HeaverView" owner:self options:nil].firstObject;
            //Now connect IBOutlets
            self.myLabel1 = viewFromNib.myLabel1;
            self.myLabel2 = viewFromNib.myLabel2;
            self.myLabel3 = viewFromNib.myLabel3;
            [viewFromNib setFrame:self.bounds];
            [viewFromNib setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
            [self addSubview:viewFromNib];
        }
    
        return self;
    }
    

    【讨论】:

    • 非常感谢,InitwithCoder 正是我想要的!
    • 快速提问,如果我在 GlobalView.xib 中以编程方式而不是在 XIB 中创建子视图会怎样?所以我可以在未来创建许多实例。我试过 - MatchView *contentView = [[MatchView alloc] initWithFrame:CGRectMake(8, 8, 327, 120)];然后将其添加为子视图。但是 UIView 是空白的。我想我得调用 initwithcoder 了?
    • 如果您想在代码中创建 HeaderView 的实例,并将其添加到您的 GlobalView,然后从 nib 加载 HeaderView(不使用 initWithFrame)并将其添加为子视图,方法与 initWithCoder 在上面的示例中相同: HeaverView *viewFromNib = [[NSBundle mainBundle] loadNibNamed:@"HeaverView" owner:self options:nil].firstObject;在 iOS 中,有两种方法可以实例化 UIView,使用 init 或 initWithFrame(不使用 NIB)或从 nib(内部调用 initWithCoder 而不是 initWithFrame)
    • 我试过这个,但得到了“以 NSException 类型的未捕获异常终止”。另外,这真的足够初始化吗?我假设你必须给它坐标或其他东西来告诉它在哪里添加它。对不起,我对 iOS 编程很陌生,因为这是我的第一个项目,所以我很容易混淆。我也读了nscookbook.com/2013/01/…
    • 放置断点并调试您的代码。验证执行 MatchView *viewFromNib = [[NSBundle mainBundle] loadNibNamed:@"MatchView " owner:self options:nil].firstObject;从笔尖返回一个 UIView,所有子视图和 IBOutlets 都已初始化。之后,您可以设置任何您想要的框架,最后使用 [self.view addSubview: viewFromNib] 将其添加为子视图
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    相关资源
    最近更新 更多