1

XCode で iPhone アプリケーションとして小さな MVC サンプル プロジェクトを作成しています。これは完全にコードで構築されているため、Interface Builder を使用しません。まず、これまでに作成したコードをお見せしたいと思います。

コントローラ

コントローラーはモデルとビューをインスタンス化し、モデルとビューの間の独立性を示す関数も含みます。

ViewController.h

#import <UIKit/UIKit.h>
#import "MainView.h"
#import "ProjectModel.h"

@interface ViewController : UIViewController

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()
{
    ProjectModel *model;
    MainView *myMainView;
}

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    model = [[ProjectModel alloc] init];

    myMainView = [[MainView alloc] initWithFrame:CGRectMake(0, 0, 320, 468)];
    [self.view addSubview:myMainView];

    //test function to illustrate that view and model are independent
    [self calculate];

}

- (void)calculate
{    
    int result = [model operationWithNumber:3 andAnotherNumber:5];
    [myMainView showResult:result];
}

@end

モデル

クラス ProjectModel はプロジェクトのモデルを担当し、この例では簡単にするために 2 つの数値の合計のみを担当します。

ProjectModel.h

#import <Foundation/Foundation.h>

@interface ProjectModel : NSObject

-(int)operationWithNumber:(int)number1 andAnotherNumber:(int)number2;

@end

ProjectModel.m

#import "ProjectModel.h"

@implementation ProjectModel

-(int)operationWithNumber:(int)number1 andAnotherNumber:(int)number2
{
    return (number1 + number2);
}

@end

意見

ビュークラスは、ビューのすべての要素を作成し、計算結果をラベルに表示する関数を含みます。 MainView.h

#import <UIKit/UIKit.h>

@interface MainView : UIView
{
    UILabel *lblResult;
}

- (void)showResult:(int)result;

@end

MainView.m

#import "MainView.h"

@implementation MainView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {        
        UILabel *lblTitle = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 50)];
        lblTitle.text = @"This is my View";
        [self addSubview:lblTitle];

        lblResult = [[UILabel alloc] initWithFrame:CGRectMake(20, 200, 280, 50)];
        lblResult.text = @"Result will be displayed here.";
        [self addSubview:lblResult];   
    }
    return self;
}

- (void)showResult:(int)result
{
    lblResult.text = [NSString stringWithFormat:@"Resultat: %d", result];
}

@end

私の質問:

ここまでのコードを理解していただければ幸いです。上記のコードに基づいて、ユーザーがこのボタンをクリックしたときに 2 つの数値を計算して表示するビュークラスにボタンを実装したいと思います。したがって、ユーザーがボタンをクリックすると、ViewController の calculate-function が呼び出される必要があります。MainView.m に次のコードでボタンを作成しました。

UIButton *btnCalculate = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btnCalculate setFrame:CGRectMake(20, 90, 280, 50)];
[btnCalculate setTitle:@"Calculate" forState:UIControlStateNormal];
[btnCalculate addTarget:self action:@selector(calculate:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btnCalculate];

問題は、上記のコードの次の行です。

[btnCalculate addTarget:self action:@selector(calculate:) forControlEvents:UIControlEventTouchUpInside];

ボタンのアクションとしてコントローラーから機能を追加するにはどうすればよいですか。関数はViewControllerで呼び出される必要があるため、ターゲットがselfであってはならないことはわかっていますが、それを行う方法がわかりません。誰かが私を助けて、この問題を解決する方法を教えてもらえますか?

現在私が確認できる唯一の解決策は、完全な GUI を ViewController で直接作成することです。しかし、MVC の主な目的は、同じクラスにコントローラーとビューのコードが混在するのを避けることであるため、これは良い解決策ではないと思います。

また、私はこのデザイン パターンにかなり慣れていないため、このコードが Apple によって伝播された MVC パターンに一般的に準拠しているかどうかも疑問に思っています。このコードに関する短いフィードバックをいただければ幸いです。

4

2 に答える 2

2

ビュー クラスにターゲットを設定しないでください。MVC の場合、ビューはコントローラーについて明示的に認識すべきではありません。ビュー クラスには、ボタンを公開するパブリック プロパティが必要であり、コントローラーはボタンを更新してターゲットを追加できます。

それ以外は、MVC のポイントを理解しているようです。

[self.view addSubview:view];この行は、ビューをそれ自体のサブビューとして追加しようとしているように見えるため、少し混乱します...

于 2013-07-29T21:26:08.620 に答える
0

MVC パターンは素晴らしいものですが、あなたのようなプログラムがその程度の分離を持つ必要はないと思います。また、ボタンは計算機能とともにそのパターンの一部であるため、ビュークラスに含めることができます。

于 2013-07-29T21:27:20.397 に答える