您好我已经阅读了有关MVC的网络教程,并且已经在这里阅读了主题。我想我得到了MVC的概念,但我不确定它的实现。
我试图将它应用于一个简单的程序,一个带有标签和按钮的窗口。 按钮增加一个计数器,标签显示它的值。
我尝试了两种不同的方式。
在第一种情况下(示例有效)我融化了视图和控制器。正如我所说,该示例有效,但我希望你们告诉我它是否是MVC的正确实现,或者它没有遵循正确的设计。
第二个示例将模型视图和控制器作为3个分离的类,但示例不起作用,因为V和C导入自身,所以我希望你们告诉我我在哪里做错了。
第一个版本:model,view-controller
//Model.h
#import <Foundation/Foundation.h>
@interface Model : NSObject {
int _counter;
}
-(void)setCounter:(int)valueCounter;
-(int)getCounter;
-(void)increaseCounter;
@end
//Model.m
#import "Model.h"
@implementation Model {}
-(void)setCounter:(int)valueCounter { _counter = valueCounter; }
-(int)getCounter { return _counter; }
-(void)increaseCounter{ _counter ++; }
@end
//ViewController.h
#import <UIKit/UIKit.h>
#import "Model.h"
@interface ViewController : UIViewController {
IBOutlet UIButton *_button;
IBOutlet UILabel *_label;
Model *myModel;
}
-(IBAction)send:(id)sender;
@end
//ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
myModel = [[Model alloc]init];
_label.text = [NSString stringWithFormat:@"%d",[myModel getCounter]];
}
- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; }
- (IBAction)send:(id)sender{
[myModel increaseCounter];
_label.text = [NSString stringWithFormat:@"%d",[myModel getCounter]];
}
@end
这是MVC的正确模式吗?代码可以工作,但在我开始更复杂的应用程序之前,我想确保我以一种好的方式对其进行编码。这就是我用这个应用程序,我的MVC方式。这不好吗?好?如何改变或修复它?
第二版:模型,视图,控制器分离
----&GT;这是模型
//Model.h
#import <Foundation/Foundation.h>
@interface Model : NSObject {
int _count;
}
-(void)setCount:(int)value;
-(int)getCount;
-(void)increaseCount;
@end
//Model.m
#import "Model.h"
@implementation Model
-(void)setCount:(int)value { _count = value; }
-(int)getCount { return _count; }
-(void)increaseCount { _count = _count++; }
@end
----&GT;这是视图
//View.h
#import <UIKit/UIKit.h>
#import "Controller.h"
@interface ViewController : UIViewController{
IBOutlet UILabel *label;
IBOutlet UIButton *button;
Controller *myController;
}
@end
//View.m
#import "ViewController.h"
#import "Controller.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
myController = [[Controller alloc]init];
}
- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; }
-(IBAction)pressButton:(id)sender{
label.text = [NSString stringWithFormat:@"%d",[myController actionIncrease]];
}
@end
----&GT;这是控制器
//Controller.m
#import <Foundation/Foundation.h>
@class "Model.h"
@class "ViewController.h"
@interface Controller : NSObject {
Model *_mymodel;
UIViewController *_myviewController;
}
-(int)actionIncrease;
@end
//Controller.m
#import "Controller.h"
#import "Model.h"
@implementation Controller
-(id)init{
_mymodel = [[Model alloc]init];
}
-(int)actionIncrease {
[_mymodel increaseCount];
return [_mymodel getCount];
}
@end
这个版本不起作用,因为类视图和控制器相互导入,编译器给我一个警告
答案 0 :(得分:24)
简单地说:UIViewController
不是你的观点,它是你的控制者
UIViewController
视为木偶操纵者,将UIView
视为傀儡。UIViewController
控制UIView上显示的内容UIView
的主要目的是包含子视图。NSObject
可供任何类使用,但应由UIViewController
使用。不可否认,在完成codechool的教程http://www.codeschool.com/courses/try-ios后,我明白了。我强烈推荐这种简单的实践方法。
让我们分解一下:
注意:我们在此处使用@property
声明。这些将使您免于编写自己的setter和getter方法。 (除非您需要为自定义功能覆盖它们)
//MyModelObject.h
#import <Foundation/Foundation.h>
@interface MyModelObject : NSObject
@property (nonatomic) int count;
@end
//MyView.h
#import <UIKit/UIKit.h>
@interface MyView : UIView
// holds it's own subviews
@property (strong, nonatomic) UIView *anotherView;
@property (strong, nonatomic) UIImageView *myImageView;
@end
//MyViewController.h
#import <Foundation/Foundation.h>
#import "MyView.h" // your custom view
#import "MyModel.h" // your custom model
@interface MyViewController : UIViewController
@property (strong, nonatomic) MyView *myView
// see how the view is "owned" by the view controller?
@end
//MyViewController.m
@implementation MyViewController
@synthesize myView;
- (void) someMethod {
[myView doSomething];
}
@end
答案 1 :(得分:1)
对于谁对将UI元素放在哪里有疑问,我经常喜欢将UI元素放在 View.m
我的策略是使所有方法都可以在View.m中构建UI元素,其中有一个方法可以调用View.m中的所有其他方法。因此,我在ViewController中仅调用一种方法
例如:
TodayView.h
#import <UIKit/UIKit.h>
@interface TodayView : UIView
@property (strong, nonatomic) UIImageView *imageView;
@property (strong,nonatomic) UINavigationBar *navBar;
-(void) addAllElements:(UIView*) mainView addController:(UIViewController*) controller;
-(void) addImage:(UIImageView*) image view:(UIView*) todayView;
-(void) addNavBar:(UIViewController*) navController addView:(UIView*)view;
@end
TodayView.m
#import "TodayView.h"
@implementation TodayView
-(void) addImage:(UIImageView *)image view:(UIView *)todayView{
image= [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
image.image = [UIImage imageNamed:@"icone-apps"];
[todayView addSubview:image];
}
-(void) addNavBar:(UIViewController *)navController addView:(UIView *)view{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 80, 120, 50)];
label.textAlignment = UITextAlignmentCenter;
[label setFont:[UIFont boldSystemFontOfSize:40.0]];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextColor:[UIColor blackColor]];
[label setText:@"Hoje"];
[navController.navigationController.navigationBar.topItem setTitleView:label];
[view addSubview:label];
}
-(void) addAllElements:(UIView *)mainView addController:(UIViewController*)controller{
[self addNavBar:controller addView:mainView];
}
@end
TodayViewController.m
#import "TodayViewController.h"
@interface TodayViewController ()
@end
@implementation TodayViewController
@synthesize myView;
-(void) blankMethod{
}
-(void) addImage:(TodayView*)todayView{
todayView.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
todayView.imageView.image = [UIImage imageNamed:@"icone-apps"];
[self.view addSubview:todayView.imageView];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
TodayView *todayView = [[ TodayView alloc] init];
# Here I call the method that call all others methods to build UI elements
[todayView addAllElements:self.view addController:self];
}
-(UITabBarItem*) tabBarItem{
return [[UITabBarItem alloc] initWithTitle:@"Hoje" image:[UIImage imageNamed:@"icone-hoje"] tag:0];
}
@end