web-dev-qa-db-ja.com

別のクラスからIBOutletにアクセスする方法

別のクラスのクラスで宣言された@IBOutletにアクセスする方法を知りたい

たとえば、myfirstviewという名前のクラスがあります

class MyFirstView: UIViewController {

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

別の.Swiftファイルに書き込まれているlblredという名前の別のクラスからMySecondViewのテキストを変更したい:

class MySecondView: UIViewController {

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

しかし、何も起こりません。
lblredをストーリーボードラベルに接続しました。私はこれについてウェブでたくさん検索しましたが、私の問題を解決できるものを見つけることができません。この問題の解決を手伝ってください。

ありがとうございました。

15
Daud 11

@Sheenはあなたの差し迫った問題については正しいですが、あなたの問題はもっと深いです。オブジェクトは、別のオブジェクトのIBOutletsにアクセスしてはなりません。何が起こるかは明確に定義されていません。これはObjCコードのバグの長い原因であり、Swiftは、これらの一般的なバグをクラッシュにエスカレートします。

ビューがロードされるまで、IBOutletsは割り当てられません。これは、View Controllerが割り当てられているが、まだ画面に表示されていない場合、IBOutletsはまだゼロであることを意味します。暗黙的にラップされていないnilにアクセスすると、Swiftがクラッシュします。

ビューコントローラは、子のビューコントローラとのみ通信する必要があります。システム内の任意のViewControllerと通信しないでください。任意のビューコントローラ間の通信は、モデルを介して行われます。 1つのViewControllerがモデルを更新し、別のViewControllerがモデルから読み取ります。これは、Cocoaのほとんどが構築されている Model-View-Controller パターンです。

ビューコントローラは子とより直接的に対話する可能性がありますが、それでもIBOutletsを直接変更しないでください。プロパティを設定する必要があります。正しい時間にそのデータをプロパティからラベルに移動するのは子ビューコントローラーの責任です(viewDidLoad()まで待たなければならない場合があります)。それが「ビューコントローラー」と呼ばれる理由です。これは、そのビューを担当する1つのオブジェクトです。他の誰もそれらを台無しにすべきではありません。

16
Rob Napier

問題はここにあります:

var lblred : UILabel! = UILabel()

ここで新しいラベルを作成します。それはあなたのIBOutlet接続を壊します。必要なのは

@IBOutlet var lblred : UILabel!
4
Sheen Vempeny

別のクラスから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";
}
0