[英]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;
我认为这不是最好的解决方案,但是它可以在您的情况下工作而不必进行太多更改。
...正如其他人已经说过的那样,您需要检查您的类名称( BMTutorialCardView
与CardView
)。
编辑:
我认为我更喜欢这种方法 。 确保将笔尖文件中的文件所有者更改为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.xib
和Beer.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.