iphonemvc。需要了解如何正确地将数据从控制器传递到视图的帮助吗

iphonemvc。需要了解如何正确地将数据从控制器传递到视图的帮助吗,iphone,model-view-controller,Iphone,Model View Controller,一点背景: 我是一名C#开发者,开始玩弄iPhone(我有一个简单2D游戏的想法)。我唯一做过的MVC编程是为web(ASP.NETMVC)做的,所以尽管我对MVC有一定的了解,但我不能只考虑一件事。这里有一个例子来说明 假设我有一个简单的应用程序,我只想在屏幕上显示一个大圆圈。我创建了一个“基于视图的应用程序”,它为我提供了一些基本类: MVCConfusionAppDelegate MVCConfusionViewController 现在,由于我将进行一些自定义绘图(我知道我可以添加一个子

一点背景:

我是一名C#开发者,开始玩弄iPhone(我有一个简单2D游戏的想法)。我唯一做过的MVC编程是为web(ASP.NETMVC)做的,所以尽管我对MVC有一定的了解,但我不能只考虑一件事。这里有一个例子来说明

假设我有一个简单的应用程序,我只想在屏幕上显示一个大圆圈。我创建了一个“基于视图的应用程序”,它为我提供了一些基本类:

MVCConfusionAppDelegate MVCConfusionViewController

现在,由于我将进行一些自定义绘图(我知道我可以添加一个子视图并以这种方式显示圆,但这只是一个较大部分的示例),我添加了一个名为MyCustomView的类,并在Interface Builder中将MVCConfusionViewController的视图设置为MyCustomView

现在问题来了。我希望能够在代码中设置自定义视图上球的大小。我在MyCusomView上有一个属性,如下所示:

#import <Foundation/Foundation.h>

@interface MyCustomView : UIView {
    NSNumber *ballSize;
}

@property(nonatomic,retain)IBOutlet NSNumber *ballSize;

@end

#import "MyCustomView.h"


@implementation MyCustomView

@synthesize ballSize;

-(void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIColor redColor]set];

    float floatValue = [self.ballSize floatValue];
    CGRect ballRect = CGRectMake(50.0f, 50.0f,floatValue , floatValue);
    CGContextFillEllipseInRect(context, ballRect);

}

@end
- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect frame = CGRectMake(0, 0, 320, 480);
    MyCustomView *myView = [[MyCustomView alloc] initWithFrame:frame];
    myView.backgroundColor = [UIColor greenColor];
    self.view = myView;
    [myView release];
    CGRect rectangle = CGRectMake(20, 20, 20, 20);
    [self.view drawRect:rectangle];
}
#导入
@接口MyCustomView:UIView{
NSNumber*球大小;
}
@属性(非原子,保留)IBN编号*球大小;
@结束
#导入“MyCustomView.h”
@实现MyCustomView
@合成球径;
-(void)drawRect:(CGRect)rect
{
CGContextRef context=UIGraphicsGetCurrentContext();
[[UIColor redColor]集];
float floatValue=[self.ballSize floatValue];
CGRect ballRect=CGRectMake(50.0f,50.0f,floatValue,floatValue);
CGContextFillEllipseInRect(上下文,ballRect);
}
@结束
然后,这里是我的MVCConfusionViewController:

#import <UIKit/UIKit.h>
#import "MyCustomView.h"

@interface MVCConfusionViewController : UIViewController {
    NSNumber *ballSize;
}

@property(nonatomic,retain)IBOutlet NSNumber *ballSize;

@end

#import "MVCConfusionViewController.h"
#import "MyCustomView.h"

@implementation MVCConfusionViewController

@synthesize ballSize;

- (void)viewDidLoad {
    [super viewDidLoad];
    MyCustomView *myView = (MyCustomView *)self.view;
    myView.ballSize = self.ballSize;
}
#导入
#导入“MyCustomView.h”
@接口MVCConfusionViewController:UIViewController{
NSNumber*球大小;
}
@属性(非原子,保留)IBN编号*球大小;
@结束
#导入“MVCConfusionViewController.h”
#导入“MyCustomView.h”
@MVCConfusionViewController的实现
@合成球径;
-(无效)viewDidLoad{
[超级视图下载];
MyCustomView*myView=(MyCustomView*)self.view;
myView.ballSize=self.ballSize;
}
最后,MVCConfusionAppDelegate:

#import <UIKit/UIKit.h>

@class MVCConfusionViewController;

@interface MVCConfusionAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    MVCConfusionViewController *viewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet MVCConfusionViewController *viewController;

@end

#import "MVCConfusionAppDelegate.h"
#import "MVCConfusionViewController.h"
#import "MyCustomView.h"

@implementation MVCConfusionAppDelegate

@synthesize window;
@synthesize viewController;


- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    viewController.ballSize = [NSNumber numberWithInt:200];
    [window addSubview:viewController.view];

    [window makeKeyAndVisible];
}


- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}


@end
#导入
@类MVCConfusionViewController;
@接口MVCConfusionAppDelegate:NSObject{
UIWindow*窗口;
MVCConfusionViewController*viewController;
}
@属性(非原子,保留)IBUIWindow*window;
@属性(非原子,保留)IBMOutlet MVCConfusionViewController*viewController;
@结束
#导入“MVCConfusionAppDelegate.h”
#导入“MVCConfusionViewController.h”
#导入“MyCustomView.h”
@实现MVCConfusionAppDelegate
@合成窗口;
@综合视图控制器;
-(void)ApplicationIDFinishLaunching:(UIApplication*)应用程序{
viewController.ballSize=[NSNumber numberwhithint:200];
[窗口添加子视图:viewController.view];
[WindowMakeKeyandVisible];
}
-(无效)解除锁定{
[视图控制器释放];
[窗口释放];
[super dealoc];
}
@结束
正如您所看到的,在我的viewDidLoad方法中有一个丑陋的演员阵容。我希望我能够在IB中连接球大小属性,但它不允许我这样做

所以我的问题很简单,在不进行强制转换的情况下,将数据从视图控制器传递到视图的正确方法是什么?我知道我遗漏了一些基本的东西,但我就是看不到。任何帮助都将不胜感激


编辑:以下是源代码。也许有人可以看看我是否做错了什么。

您的视图应该已经设置在IB中,这样您就可以按原样使用它了。如果要使用
MyCustomView
,可以这样做:

#import <Foundation/Foundation.h>

@interface MyCustomView : UIView {
    NSNumber *ballSize;
}

@property(nonatomic,retain)IBOutlet NSNumber *ballSize;

@end

#import "MyCustomView.h"


@implementation MyCustomView

@synthesize ballSize;

-(void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIColor redColor]set];

    float floatValue = [self.ballSize floatValue];
    CGRect ballRect = CGRectMake(50.0f, 50.0f,floatValue , floatValue);
    CGContextFillEllipseInRect(context, ballRect);

}

@end
- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect frame = CGRectMake(0, 0, 320, 480);
    MyCustomView *myView = [[MyCustomView alloc] initWithFrame:frame];
    myView.backgroundColor = [UIColor greenColor];
    self.view = myView;
    [myView release];
    CGRect rectangle = CGRectMake(20, 20, 20, 20);
    [self.view drawRect:rectangle];
}

我无法使您的绘图代码正常工作,对此我不太了解。

您的视图应该已经在IB中设置好了,这样您就可以按原样使用它了。如果要使用
MyCustomView
,可以这样做:

#import <Foundation/Foundation.h>

@interface MyCustomView : UIView {
    NSNumber *ballSize;
}

@property(nonatomic,retain)IBOutlet NSNumber *ballSize;

@end

#import "MyCustomView.h"


@implementation MyCustomView

@synthesize ballSize;

-(void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIColor redColor]set];

    float floatValue = [self.ballSize floatValue];
    CGRect ballRect = CGRectMake(50.0f, 50.0f,floatValue , floatValue);
    CGContextFillEllipseInRect(context, ballRect);

}

@end
- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect frame = CGRectMake(0, 0, 320, 480);
    MyCustomView *myView = [[MyCustomView alloc] initWithFrame:frame];
    myView.backgroundColor = [UIColor greenColor];
    self.view = myView;
    [myView release];
    CGRect rectangle = CGRectMake(20, 20, 20, 20);
    [self.view drawRect:rectangle];
}

我无法使您的绘图代码正常工作,对此我知道的不多。

避免强制转换的一种方法是为控制器上的自定义视图添加单独的outlet属性,并参考该属性


在Interface Builder中,创建
MyCustomView
的实例,并将其拖动到现有视图中,使其成为子视图,然后将其附加到控制器上自己的插座上。

避免强制转换的一种方法是为控制器上的自定义视图添加单独的插座属性,并改为引用该属性


在Interface Builder中,创建
MyCustomView
的实例,并将其拖动到现有视图中,使其成为子视图,然后将其连接到控制器上自己的插座。

是否尝试将一个IBOutlet(控制器中)连接到另一个IBOutlet(视图中)?不幸的是,我觉得没那么容易:-)

您还将数据(ballSize)存储在控制器和视图中

我将使MVCConfusionViewController成为MyCustomView的数据源,然后让MyCustomView在-drawRect:方法中向其数据源询问球的大小

@class MyCustomView;

@protocol MyCustomViewDataSource
- (NSNumber *)ballSizeForMyCustomView:(MyCustomView *)view;
@end

@interface MyCustomView {
    id<MyCustomViewDataSource> dataSource;
}
@property (nonatomic, assign) IBOutlet id<MyCustomViewDataSource> dataSource;
@end

@implementation MyCustomView
- (void)drawRect:(CGRect) rect {
    if (self.dataSource == nil) {
        // no data source, so we don't know what to draw
        return;
    }

    float floatValue = [[self.dataSource ballSizeForMyCustomView:self] floatValue];
    // ...
}
@end

您是否正在尝试将一个IBOutlet(在控制器中)连接到另一个IBOutlet(在视图中)?不幸的是,我觉得没那么容易:-)

您还将数据(ballSize)存储在控制器和视图中

我将使MVCConfusionViewController成为MyCustomView的数据源,然后让MyCustomView在-drawRect:方法中向其数据源询问球的大小

@class MyCustomView;

@protocol MyCustomViewDataSource
- (NSNumber *)ballSizeForMyCustomView:(MyCustomView *)view;
@end

@interface MyCustomView {
    id<MyCustomViewDataSource> dataSource;
}
@property (nonatomic, assign) IBOutlet id<MyCustomViewDataSource> dataSource;
@end

@implementation MyCustomView
- (void)drawRect:(CGRect) rect {
    if (self.dataSource == nil) {
        // no data source, so we don't know what to draw
        return;
    }

    float floatValue = [[self.dataSource ballSizeForMyCustomView:self] floatValue];
    // ...
}
@end

好吧,这很有道理。我现在将尝试使用这种方法来实现它。如果它可行并且有意义,我会接受你的回答。谢谢好吧,我接受这个答案。这似乎是最合乎逻辑的方法,我喜欢协议方法。解耦控制器和视图。不过,我必须更改代码,protol方法不需要将视图作为参数。事实上,这会导致循环引用,并且不会生成循环引用。谢谢你的帮助,真的吗?嗯,我只是把这些都输入了浏览器。不管怎样,我很高兴我能