【问题标题】:iOS - Implementation of MVC-Pattern without Interface BuilderiOS - 没有 Interface Builder 的 MVC 模式的实现
【发布时间】:2013-07-29 21:16:43
【问题描述】:

我正在创建一个小的 MVC 示例项目作为 XCode 中的 iPhone 应用程序,它完全用代码构建,因此不使用 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 类负责项目的模型,在这个例子中为了简单起见只负责总结两个数字:

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

我的问题:

我希望你到目前为止已经理解了代码。基于上面的代码,我想在视图类中实现一个按钮,当用户点击这个按钮时,它应该计算并显示两个数字。因此,当用户单击按钮时,应调用 ViewController 中的计算函数。我在 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];

如何从控制器添加一个功能作为按钮的操作。我知道目标不应该是 self,因为该函数应该在 ViewController 中调用,但我不知道该怎么做。谁能帮助我并告诉我如何解决这个问题?

我现在能看到的唯一解决方案是直接在 ViewController 中创建完整的 GUI。但我不认为这是一个很好的解决方案,因为 MVC 的主要目的是避免在同一个类中混合控制器和视图代码。

我还想知道这段代码是否通常符合 Apple 传播的 MVC 模式,因为我对这种设计模式还很陌生。非常感谢您对此代码的简短反馈。

【问题讨论】:

    标签: objective-c model-view-controller


    【解决方案1】:

    不要在视图类中设置目标。对于 MVC,视图不应该明确知道控制器。视图类应该有一个公共属性来公开按钮,然后控制器可以更新按钮以添加目标。

    除此之外,您似乎了解 MVC 的意义。

    这一行确实有点混淆了[self.view addSubview:view];,因为它似乎试图将视图添加为自身的子视图...

    【讨论】:

    • 这一行听起来确实有点奇怪。 view 是 MainView 的一个实例,并被添加到 ViewController 的视图中,因此它得到了实际显示。也许我应该称它为 myMainView 或类似的名称。我将在我的开场白中改变这一点。你的解决方案听起来很有趣,我会试试的。
    • 是的,因为视图控制器已经有 view 属性,所以调用视图不同。
    • 我通过将 MainView 中的按钮设为公共并在 ViewController 中添加此语句来实现您的解决方案: [myMainView.btnCalculate addTarget:self action:@selector(calculate:) forControlEvents:UIControlEventTouchUpInside];它可以工作并且看起来很漂亮。感谢您的帮助!
    【解决方案2】:

    MVC 模式是个好东西,但我认为像你这样的程序没有必要有这种程度的分离。按钮也可以在视图类中,因为它是该模式的一部分以及计算功能。

    【讨论】:

    • 是的,对于这种项目,MVC 模式不是必需的。这个项目只是为了以一种简单易懂的方式向社区说明我的想法和想法。到目前为止,我在 ViewController 中编写了所有内容(控制器、模型和视图),导致应用程序在这个唯一的文件中有数千行代码,这变得非常混乱。这就是我想学习这种设计模式的原因。
    • 不确定是否有一种精确的方法可以真正分离所有内容,我相信可能有。肯定你是对的,因为许多程序往往有非常厚实的视图控制器,事实上,一些苹果示例也做得很好,不仅仅是我们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多