繁体   English   中英

无法在以编程方式加载的XIB中访问和设置UILabel的文本

[英]Can't access and set Text of UILabel in a programmatically loaded XIB

这是我第一次在StackOverflow上发帖-太长了我一直在发这篇文章。 希望社区能够有所帮助。

我已经设置了UIScrollView / PageControl来翻页4页。 我试图将.xib加载到ScrollView中4次,每次使用不同的文本和图像。

不幸的是,我能够加载xib,但无法更改文本/图像,我不确定为什么。 我认为这可能与无法访问ViewController中已加载的NIB的UILabel有关。

这是CardView.xib(CardView.h)的.h文件:

#import <UIKit/UIKit.h>

@interface BMTutorialCardView : UIView

@property (strong, nonatomic) IBOutlet UIView *contentView;
@property (weak, nonatomic) IBOutlet UIImageView *cardImage;
@property (weak, nonatomic) IBOutlet UILabel *cardLabel;

@end

这是CardView.m文件:

#import "CardView.h"

@implementation CardView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        UIView *xibView = [[[NSBundle mainBundle] loadNibNamed:@"BMTutorialCardView" owner:self options:nil] objectAtIndex:0];
        [self addSubview:xibView];
    }
    return self;
}
@end

我将UIImageView和UILabel插座从xib连接到CardView.h。

现在在ViewController中,将xib添加4次到scrollView中:

@implementation BMViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    for (int i = 0; i < 4; i++) {
        CGRect frame;
        frame.origin.x = self.scrollView.frame.size.width * i;
        frame.origin.y = 0;
        frame.size = self.scrollView.frame.size;

        CardView *subview = [[BMTutorialCardView alloc] initWithFrame:frame];

        //The following line doesn't change the text.
        subview.cardLabel.text = @"This line doesn't change the text on the label";
        [self.scrollView addSubview:subview];
    }

    self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * 4, self.scrollView.frame.size.height);
}

我不确定为什么subview.cardLabel.text实际上没有更改文本。 看来subview.cardLabel是nil,但我清楚地看到了运行iOS模拟器时,UILabel带有我在xib中具有的默认文本。

OK,假设您已经在界面构建器中创建了xib并链接了IBOutlets,我认为initWithFrame中的这些行

UIView *xibView = [[[NSBundle mainBundle] loadNibNamed:@"BMTutorialCardView" owner:self options:nil] objectAtIndex:0];
[self addSubview:xibView];

实际上是在视图顶部创建一个视图,因此尽管您正在更改在界面中创建的标签,但是由于已将所有重复视图叠加在所有视图之上,因此您无法看到更改。 尝试取出我上面引用的内容。

编辑:另外,就像Phillip指出的那样,为什么.m和文件名中的其他所有内容都为“ CardView”时,为什么CardView.h会说“ BMTutorialCardView”,为什么要使用“ BMTutorialCardView” xib初始化视图? 您是否将彼此混淆的两个单独的类? 实际上,我越看待您的代码,就对您正在尝试做的事情越困惑……

替换以下两行:

UIView *xibView = [[[NSBundle mainBundle] loadNibNamed:@"BMTutorialCardView" owner:self options:nil] objectAtIndex:0];
[self addSubview:xibView];

有了这个:

self = [[[NSBundle mainBundle] loadNibNamed:@"CardView" owner:self options:nil] objectAtIndex:0];
self.frame = frame;

我认为这不是最好的解决方案,但是它可以在您的情况下工作而不必进行太多更改。

...正如其他人已经说过的那样,您需要检查您的类名称( BMTutorialCardViewCardView )。

编辑:

我认为我更喜欢这种方法 确保将笔尖文件中的文件所有者更改为UIViewController并将其view出口连接到CardView (或调用UIView子类的任何类)。

然后,您可以完全删除initWithFrame:方法中无法使用的代码,并在viewDidLoad替换此行:

CardView *subview = [[BMTutorialCardView alloc] initWithFrame:frame];

有了这个:

UIViewController *controller = [[UIViewController alloc] initWithNibName:@"CardView" bundle:nil];
CardView *subview = (CardView *)controller.view;
subview.frame = frame;

这个问题大概可以通过View Life Cycle来解决 假设我们有单独的视图插图Beer.xibBeer.class (其中Beer.class内部视图的子视图在此处以Beer.class形式存储在@IBOutlets )。 最后,我们有BeerInfoViewController.swift (由UIViewController继承)。 首先,我们需要将BeerInfoViewController加载到BeerInfoViewController (对Swift感到抱歉,对于Objective-C来说还太年轻):

override func viewDidLoad() {
    super.viewDidLoad()
    guard let beerXib = Bundle.main.loadNibNamed("Beer", owner: self, options: nil)?.first as? BeerInfoViewController else {
        fatalError("Beer.xib is not found. 🍺❌👎🏻")
    }
    beerXib.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
    self.view.addSubView(beerXib)
}

好的, Beer.xib已加载到BeerInfoViewController的根视图中。 接下来,您需要访问@IBOutlets中的Beer.class 不要再说了

beerXib.subviews.forEach { subView in
    // Do whatever you want to do with subviews! 🍻
}

哎呀。 不要忘记在情节.xib中为您明确定义一个类。 您必须在身份检查器中执行此操作,或者默认情况下,只需在Xcode中键入cmd + option + 3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM