【问题标题】:Multiple XIBs embeded in UIStackViews displayed in one StoryBoard with UIStackViewsUIStackView 中嵌入的多个 XIB 使用 UIStackView 显示在一个 StoryBoard 中
【发布时间】:2018-03-16 01:46:54
【问题描述】:

我正在使用多个 XIB/Storyboard 来构建我的应用程序。

我的观点在 XIB 中列出。有些有UIStackView 来帮助组织布局。

我的主情节提要有两个嵌入在 UIStackView 中的视图,它们会拉入使用 XIBs 创建的视图。

什么都不会正确显示。尽管在界面生成器中正确显示,但视图大小不正确或根本不显示。

我怀疑视图正在显示,之前它们已完全加载到视图中,导致框架大小不同。

有人告诉我,最好的做法是为视图提供自己的 Storyboard/XIB,以便更好地合并、维护等...这就是我想要学习的内容。

有人知道完成我正在做的事情的正确方法吗?

这是我正在做的事情:

视图控制器

#import "OrangeView.h"
#import "GreenView.h"

@interface ViewController () {
    OrangeView *ov;
    GreenView *gv;
}

@property (weak, nonatomic) IBOutlet UIView *viewOrange;
@property (weak, nonatomic) IBOutlet UIView *viewGreen;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //Load Orange View
    ov = [[OrangeView alloc] initWithFrame:_viewOrange.frame];
    [_viewOrange addSubview:ov];

    //Load GreenView
    gv = [[GreenView alloc] initWithFrame:_viewGreen.frame];
    [_viewGreen addSubview:gv];

}

主故事板

OrangeView

GreenView(带有多个堆栈视图)

概览

【问题讨论】:

  • 使用单独的 Storyboards / xib 文件可能会有所帮助,具体取决于您的应用程序的复杂性。有时,他们可能比他们的价值更麻烦。如果您想从 xib 加载视图 + 子视图,您需要做的不仅仅是实例化类。你在这里的最终目标是什么?你想让你的 xib 视图加载和 缩放 以适应指定的框架吗?你想加载 xib 视图并让它们的“内部”框架/约束决定它们的大小吗?
  • 前者。我希望子视图可以缩放以适合指定的框架。

标签: ios objective-c storyboard xib uistackview


【解决方案1】:

.xib 文件的内容没有“链接”到类。也就是说,当您实例化该类时,它本身不会加载您在 xib 中布置的视图和子视图。

有几种方法可以解决这个问题。一种方法是在视图类中包含“加载元素”代码。这允许加载/创建视图实例、添加为子视图、设置参数(框架或约束)等更“常规”的方法。

这是一个使用“xib-load”函数子类化UIView 的示例,然后使您的实际类成为此“基础”的子类:


//
//  XIBViewBase.h
//

#import <UIKit/UIKit.h>

@interface XIBViewBase : UIView

@end

//
//  XIBViewBase.m
//

#import "XIBViewBase.h"

@implementation XIBViewBase

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

    if (self) {
        [self xibSetup];
    }

    return self;
}

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];

    if (self) {
        [self xibSetup];
    }

    return self;
}

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

- (void)xibSetup {

    // make sure we don't add the subviews more than once
    if (!self.subviews.count) {

        UIView *view = [self loadFromXIB];

        view.frame = self.bounds;
        view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

        [self addSubview:view];
        [self sendSubviewToBack:view];

    }

}

- (UIView *)loadFromXIB {

    // Note: the .xib file MUST be named the same as the class for this to work

    NSString *className = NSStringFromClass([self class]);
    NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    UINib *nib = [UINib nibWithNibName:className bundle:bundle];
    UIView *v = [nib instantiateWithOwner:self options:nil].firstObject;

    return v;

}

@end

我整理了一个示例(使用您的目标),您可以查看一下。可能会帮助您处理它:

https://github.com/DonMag/SimpleXIB


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    相关资源
    最近更新 更多