2

IB を使用せずに、ラベルを含むビューを表示する基本的なテスト アプリをセットアップしました。カスタム UIView サブクラスとカスタム UIViewController サブクラスを使用したいと考えています。

これは予想どおりに実行されますが、MyViewController の viewWillAppear および他の同様のデリゲートは起動しません。

これらの火をつけるために何が欠けていますか?以前のプロジェクト (IB を使用) では、これらは問題なく起動しました。

完全なコードは次のとおりです。

AppDelegate - 「MainVC」ビュー コントローラをロードし、ルート コントローラとして設定します

#import "AppDelegate.h"
#import "MainVC.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize mainVC = _mainVC;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.mainVC = [[MainVC alloc] init];
    self.window.rootViewController = self.mainVC;
    [self.window makeKeyAndVisible];
    return YES;
}

MainVC - 「MyView」を割り当てる「MyViewController」を作成します (ビューに使用するフレーム サイズも渡します)。

#import "MainVC.h"
#import "MyViewController.h"

@implementation MainVC

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        MyViewController *controller = [[MyViewController alloc] init];
        CGRect frame;
        frame.origin.x = 5;
        frame.origin.y = 5;
        frame.size.width = self.view.frame.size.width - (2 * 5);
        frame.size.height = self.view.frame.size.height - (2 * 5);
        controller.startingFrame = frame;
        [self.view addSubview:controller.view];
    }
    return self;
}

MyViewController - MyView を作成します

#import "MyViewController.h"
#import "MyView.h"

@implementation MyViewController

@synthesize startingFrame;

- (void)loadView{
    self.view = [[MyView alloc] initWithFrame:startingFrame];
}

- (void)viewWillAppear:(BOOL)animated{
    NSLog(@"appearing"); //doesn't do anything
}

- (void)viewDidAppear:(BOOL)animated{
    NSLog(@"appeared"); //doesn't do anything
}

私の見解

#import "MyView.h"

@implementation MyView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        label = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 150, 40)];
        [label setText:@"Label"];
        [self addSubview:label];
    }
    return self;
}
4

3 に答える 3

3

あなたの間違い:ルート ビュー コントローラーを設定し、その上に別のビュー コントローラー ビューを追加しています。2 番目のビューがビュー階層に追加されている間、そのビュー コントローラーはこのように「配線されていない」ままです。実際、MainViewController の parentViewController を確認すると、nil.

理由: viewWillAppear メソッドは、ルート ビュー コントローラー、またはルート ビュー コントローラーの階層内のビュー コントローラー (presentModalViewController:animated:またはを使用して提示されたものpresentViewController:animated:completion:) にのみ送信されます。

解決策:それを解決するには、いくつかのオプションがあります:

  1. ビュー コントローラーをルート ビュー コントローラーとして使用する
  2. 上記のいずれかの方法でView Controllerを提示します
  3. コードをそのままにして、それらのイベントを手動で子ビュー コントローラーに配線します (ただし、この方法には注意してください。あなたが言及したイベントは iOS 5 で自動的に転送されると思われるため、簡単に確認できます)。
  4. これらのイベントをView Controllerに転送する別の方法を正しく思い出せば、View Controllerのビューを親ビューではなくウィンドウに追加することです。
于 2012-05-29T15:26:01.680 に答える
2

非常に基本的な問題がいくつかあります。

  • initWithNibNamed:MainViewController のセットアップ全体を行っていますが、呼び出しだけで作成していますinit。だからあなたのセットアップは決して起こりません
  • どうやら myView を作成するためだけに 2 番目の VC (MyViewController) を実装し、それを rootVCs 階層に追加します。良くない!階層内のビューの作成と管理を担当するのは、単一の VC (この場合は MainViewController) だけです。
  • loadViewMyViewController で行ったように、でVC コントローラーのセットアップを行わないでください。あなたの場合、MyVCが実際に完全に稼働することは決してないため、物事を機能させる唯一の方法ですが、アプローチは間違っています-コントローラー自体は決してありませんが、基本的にビューコントローラーにビューを設定するように強制しています何でもコントロール

他にもいくつかありますが、それらは最も重要なものです。モデル - ビュー - コントローラーの概念の基本概念全体についてもう一度読むことをお勧めします。次に、UIViewControllerUIViewの両方のクラス参照を掘り下げる必要があります。

現在のアプローチを使用して最終的に希望する結果が得られたとしても、関連する要素を適切に使用することを学べないため、長期的には役に立ちません。

于 2012-05-29T15:52:18.287 に答える
0

メソッドは、別のViewController内のViewControllerでは呼び出されません。iOS 5のみを対象に開発している場合は、これを解決するために使用できるUIViewControllerContainmentを確認してください。アプリケーションを以前のiOSバージョンと互換性があるようにする場合は、メソッド呼び出しを子ViewControllerに転送できます。個人的には、これを自動的に処理するSFContainerViewControllerをサブクラス化することを好みます: https ://github.com/krzysztofzablocki/SFContainerViewController

于 2012-06-04T18:08:06.973 に答える