如何从另一个类访问IBOutlet

时间:2022-05-03 16:59:09

I want to know how to access an @IBOutlet declared in a class from another class

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

for example, I have a class named myfirstview

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

class MyFirstView: UIViewController {

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

I want to change the text of the lblred from another class named MySecondView which is written in another .swift file:

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

class MySecondView: UIViewController {

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

But nothing happens.
I have connected lblred with a storyboard label. I have searched a lot about this on the web but I can't find the one which can solve my problem. Please help me solve this problem.

但没有任何反应。我已将lblred与故事板标签连接起来。我在网上搜索过很多关于这个但我找不到可以解决我问题的那个。请帮我解决这个问题。

Thank you.

谢谢。

3 个解决方案

#1


13  

@Sheen is correct about your immediate problem, but your problem is deeper. No object should access another object's IBOutlets. It's not well defined what will happen. This has been a long source of bugs in ObjC code, and Swift escalates those common bugs to crashes.

@Sheen对你的直接问题是正确的,但你的问题更深入。没有对象应该访问另一个对象的IBOutlets。它没有明确定义会发生什么。这是ObjC代码中的一个长期错误来源,Swift将这些常见错误升级为崩溃。

IBOutlets are not assigned until the view is loaded. This means that if the view controller is allocated but has not been put on the screen yet, the IBOutlets are still nil. Accessing an implicitly unwrapped nil will crash Swift.

在加载视图之前,不会分配IBOutlet。这意味着如果视图控制器已分配但尚未放在屏幕上,则IBOutlets仍为零。访问一个隐式解包的nil会使Swift崩溃。

View controllers should only communicate with their children view controllers. They should not communicate with arbitrary view controllers in the system. Communication between arbitrary view controllers is done via the model. One view controller updates the model, and another view controller reads from the model. This is the Model-View-Controller pattern that most of Cocoa is built around.

视图控制器只应与其子视图控制器通信。它们不应与系统中的任意视图控制器通信。任意视图控制器之间的通信是通过模型完成的。一个视图控制器更新模型,另一个视图控制器从模型中读取。这是模型 - 视图 - 控制器模式,大多数Cocoa都是围绕它构建的。

View controllers may interact more directly with their children, but still should not modify IBOutlets directly. They should set properties. It is the child view controller's responsibility to move that data from the property to the label at the correct time (which may have to wait until viewDidLoad()). That's why it's called the "view controller." It is the one object responsible for its views. No one else should mess with them.

视图控制器可以更直接地与其子级进行交互,但仍不应直接修改IBOutlet。他们应该设置属性。子视图控制器有责任在正确的时间将该数据从属性移动到标签(可能必须等到viewDidLoad())。这就是它被称为“视图控制器”的原因。它是负责其观点的一个对象。别人不应该搞砸他们。

#2


4  

Problem is here :

问题在这里:

var lblred : UILabel! = UILabel()

You creating a new label here. That breaking your IBOutlet connection. You only need

您在此处创建新标签。这打破了你的IBOutlet连接。你只需要

@IBOutlet var lblred : UILabel!

#3


0  

Its not the recommended way to call a IBOutlet from another class. If u want to call or access a IBOutlet then you should set it as property and then access it.

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

For example:

例如:

//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";
}

#1


13  

@Sheen is correct about your immediate problem, but your problem is deeper. No object should access another object's IBOutlets. It's not well defined what will happen. This has been a long source of bugs in ObjC code, and Swift escalates those common bugs to crashes.

@Sheen对你的直接问题是正确的,但你的问题更深入。没有对象应该访问另一个对象的IBOutlets。它没有明确定义会发生什么。这是ObjC代码中的一个长期错误来源,Swift将这些常见错误升级为崩溃。

IBOutlets are not assigned until the view is loaded. This means that if the view controller is allocated but has not been put on the screen yet, the IBOutlets are still nil. Accessing an implicitly unwrapped nil will crash Swift.

在加载视图之前,不会分配IBOutlet。这意味着如果视图控制器已分配但尚未放在屏幕上,则IBOutlets仍为零。访问一个隐式解包的nil会使Swift崩溃。

View controllers should only communicate with their children view controllers. They should not communicate with arbitrary view controllers in the system. Communication between arbitrary view controllers is done via the model. One view controller updates the model, and another view controller reads from the model. This is the Model-View-Controller pattern that most of Cocoa is built around.

视图控制器只应与其子视图控制器通信。它们不应与系统中的任意视图控制器通信。任意视图控制器之间的通信是通过模型完成的。一个视图控制器更新模型,另一个视图控制器从模型中读取。这是模型 - 视图 - 控制器模式,大多数Cocoa都是围绕它构建的。

View controllers may interact more directly with their children, but still should not modify IBOutlets directly. They should set properties. It is the child view controller's responsibility to move that data from the property to the label at the correct time (which may have to wait until viewDidLoad()). That's why it's called the "view controller." It is the one object responsible for its views. No one else should mess with them.

视图控制器可以更直接地与其子级进行交互,但仍不应直接修改IBOutlet。他们应该设置属性。子视图控制器有责任在正确的时间将该数据从属性移动到标签(可能必须等到viewDidLoad())。这就是它被称为“视图控制器”的原因。它是负责其观点的一个对象。别人不应该搞砸他们。

#2


4  

Problem is here :

问题在这里:

var lblred : UILabel! = UILabel()

You creating a new label here. That breaking your IBOutlet connection. You only need

您在此处创建新标签。这打破了你的IBOutlet连接。你只需要

@IBOutlet var lblred : UILabel!

#3


0  

Its not the recommended way to call a IBOutlet from another class. If u want to call or access a IBOutlet then you should set it as property and then access it.

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

For example:

例如:

//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";
}