web-dev-qa-db-ja.com

nibをロードしましたが、ビューアウトレットが設定されていませんでした-Swift edition

私は、Swiftにあるビューコントローラーを除いて、すべてObjective Cにあるプロジェクトを持っています。

実行するとエラーが発生する

キャッチされない例外 'NSInternalInconsistencyException'によりアプリを終了しています。理由: '-[UIViewController _loadViewFromNibNamed:bundle:]は "..." nibをロードしましたが、ビューアウトレットが設定されていませんでした。'

それで、nibファイルを開いて、「ファイルの所有者」を見ると、ビューがアウトレットとしてまったく表示されていないことがわかりました。
私の古いView Controller(Objective C)では、Viewアウトレットが表示されます。

私のSwiftビューコントローラでは、@ View変数を強制的に@IBOutletにするために、UIViewControllerの「view」変数をオーバーライドしようとしましたが、「view」変数がタイプUIViewであるという不満がありました。 UIView?とUIView!に文句を言いました。

ここに簡略化されたバージョンがあります

私のAppDelegate.h

#import <UIKit/UIKit.h>

@class MyViewController;
@class MyViewControllerSwift;

@interface MSAppDelegate : UIResponder <UIApplicationDelegate>
{
}

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) UIViewController *viewController;

@end

AppDelegate.m

#import "MyAppDelegate.h"

#import "MyViewController.h"
#import "MySwift-Swift.h"
#import <UIKit/UIKit.h>

@implementation MyAppDelegate

static BOOL USE_Swift_VIEW_CONTROLLER = YES;

- (void)dealloc
{
    [_window release];
    [_viewController release];
    [super dealloc];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.

    id viewControllerPtr = nil;
    if(USE_Swift_VIEW_CONTROLLER)
    {
        viewControllerPtr = [MyViewControllerSwift alloc];
    }
    else
    {
        viewControllerPtr = [MyViewController alloc];
    }

    UIViewController* vController = nil;
    if(USE_Swift_VIEW_CONTROLLER)
    {
        vController = [[viewControllerPtr initWithNibName:@"MyViewControllerSwift" bundle:nil] autorelease];
    }
    else
    {
        vController = [[viewControllerPtr initWithNibName:@"MyViewController" bundle:nil] autorelease];
    }

    self.viewController = vController;
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];

    return YES;
}

ViewController.Swift

import Foundation
import AVFoundation

@objc class MyViewControllerSwift : UIKit.UIViewController {

    var player : AVFoundation.AVAudioPlayer?;

    @IBOutlet weak var myTextView : UITextView!;

    required init(coder aDecoder : NSCoder) {
        super.init(coder:aDecoder);
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName:nibNameOrNil, bundle:nibBundleOrNil);
    }

    override func viewDidLoad() {
        super.viewDidLoad();

        println("Using MyViewControllerSwift");
    }

    deinit {
        //TODO
    }
}

ビューを表示するにはどうすればよいですか?

ありがとう。

(はい、これは ロードされたnibですが、ビューアウトレットが設定されていません-InterfaceBuilderの新機能 と同様の質問ですが、ビューアウトレットは表示されません。)

19
cowlinator
  • まず、nibファイルにカスタムクラスを設定します(ファイルの所有者-> 3番目のアイコン->カスタムクラス:YourViewController)
  • 2番目-ファイルの所有者の最後のアイコン->「ビュー」プロパティをインターフェースビューにリンク(ドラッグ)

次のようにViewControllerを初期化します。

YourViewController(nibName: "YourViewName", bundle: nil)

それが動作します。ビューで操作を行わないでください。

39
user3677173

すべてを試してもこのエラーが発生する場合は、最初からクラスファイルを再作成してください。ただし、[XIBファイルも作成する]チェックボックスをオンにしてください。これにより、これらのファイルを個別に作成するときにリンクされていないいくつかのアイテムが自動的にリンクされます。これが作成されたら、おそらくすべてを新しいXIBにカットアンドペーストすることができ、問題なく動作するはずです。

私は特にSwiftでファイルを個別に作成することでこの問題を見つけています。

11
Travis M.

同じ問題が発生しました。ビューコントローラーの2番目のビューを読み込めませんでした。プロパティでビューの名前を変更しました(以前に "View"を指定したように)。あなたの既存のView Controllerはすでに同じ名前(View)のビューへの参照を持っています。したがって、エラー。コンセント名を変更してみてください。それは私の場合完璧に働いた。

1
user5553647

中国のフォーラムで、ViewControllerとXIBからのビューに同様の名前を付けた場合に発生する可能性があることがわかりました。

SpecialOfferViewControllerおよびSpecialOfferView

名前を変更しました

SpecialOfferViewControllerおよびOfferViewおよびエラーが発生しました!!!

0
Leonif

FooViewという名前のxibファイルとFooViewControllerという名前のビューコントローラークラスがありました。

FooVewFooViewControllerのルートビューになることを意図したものではなく、サブビューのみでした。しかし、UIViewControllerのデフォルトの動作は 自動的にそれを自動的に試行する です。したがって、コントローラーのviewにアクセスした最初の時点で、このエラーによりアプリがクラッシュしました。

この動作は、次のいずれかを使用して回避できます。

  1. コントローラクラスまたはxibファイルの名前を変更して、関連付けを解除します
  2. _override var nibName: String? { nil }_
  3. override func loadView()viewに自分で割り当て

私が2で行ったのは、後でこっそり私に噛み付く可能性が最も低いと思われたためです。

0