如何从另一个类中访问IBOutlet

16

我想知道如何从另一个类中访问在一个类中声明的 @IBOutlet。

例如,我有一个名为 myfirstview 的类。

class MyFirstView: UIViewController {

    @IBOutlet var lblred: UILabel! = UILabel()
}

我想从另一个名为MySecondView的类中更改lblred的文本,该类编写在另一个.swift文件中:

class MySecondView: UIViewController {

    func modify() {
        let mfv = MyFirstView()
        mfv.lblred.text = "Hello"
    }
}

但是什么也没有发生。
我已经将lblred与一个故事板标签连接起来了。我在网上搜索了很多关于这个问题的内容,但是我找不到可以解决我的问题的内容。请帮助我解决这个问题。

谢谢。


please format the code - Paolo Fulgoni
3个回答

18
@Sheen在解决你的即时问题方面是正确的,但你的问题更深层次。没有对象应该访问另一个对象的IBOutlets,这不是很明确会发生什么。这一直是ObjC代码中的一个长期存在的错误源,而Swift将这些常见的错误升级为崩溃。
只有在视图加载后,才会分配IBOutlets。这意味着,如果视图控制器已经被分配但尚未放置在屏幕上,则IBOutlets仍然为nil。访问隐式解包的nil将导致Swift崩溃。
视图控制器应该只与其子视图控制器通信,而不应该与系统中的任意视图控制器通信。任意视图控制器之间的通信是通过模型完成的。一个视图控制器更新模型,另一个视图控制器从模型中读取。这是大多数Cocoa构建在其上的Model-View-Controller模式。

视图控制器可以直接与其子控制器交互,但仍不应直接修改IBOutlets。它们应该设置属性。将数据从属性移动到标签是子视图控制器的责任,在正确的时间(可能要等到viewDidLoad())进行操作。这就是为什么它被称为“视图控制器”的原因。它是负责其视图的唯一对象。没有其他人应该干预它们。


4
这里出现了问题:
var lblred : UILabel! = UILabel()

在这里您正在创建一个新的标签。这将会破坏您的IBOutlet连接。您只需要


@IBOutlet var lblred : UILabel!

1
当我这样做时,结果显示:致命错误:在解包可选值时意外发现了nil。 - Daud 11
它显示了 IBOutlet 没有可选类型 UILabel 的错误。但是,感谢你的帮助。 - Daud 11

0

从另一个类中调用IBOutlet不是推荐的方法。如果您想要调用或访问IBOutlet,则应将其设置为属性,然后访问它。

例如:

//ViewControler.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *label;

@end

//abc.m

#import <UIKit/UIKit.h>
#import <ViewController.h>

@interface abc

@end

@implementation abc

- (void)viewDidLoad
{
[super viewDidLoad];
ViewController *viewCOntroller= [ViewController alloc] init];
viewCOntroller.label.text = @"Hello";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接