所有。我正在尝试按照教程让iPhone在iPhone的屏幕上反弹。本教程在MVC方案中构造应用程序。当涉及到View实现中的drawRect方法时,我无法绕过这个概念。
这是我的Model头文件:
#import <Foundation/Foundation.h>
#import "TestView.h"
#define BALL_SIZE 20.0
#define VIEW_WIDTH 320.0
#define VIEW_HEIGHT 460.0
@interface TestModel : NSObject
{
TestView* ball;
CGPoint ballVelocity;
CGFloat lastTime;
CGFloat timeDelta;
}
- (void) updateModelWithTime:(CFTimeInterval) timestamp;
- (void) checkCollisionWithScreenEdges;
@property (readonly) TestView* ball;
@end
本教程指示用户覆盖NSObject的init方法。我还提供了控制“动画”逻辑的方法:
- (id) init {
self = [super init];
if (self) {
ball = [[TestView alloc] initWithFrame: CGRectMake(0.0, 0.0, BALL_SIZE, BALL_SIZE)];
// Set the initial velocity for the ball
ballVelocity = CGPointMake(200.0, -200.0);
// Initialize the last time
lastTime = 0.0;
}
return self;
}
- (void) checkCollisionWithScreenEdges {
// Left Edge
if (ball.frame.origin.x <= 0) {
ballVelocity.x = abs(ballVelocity.x);
}
// Right Edge
if (ball.frame.origin.x >= VIEW_WIDTH - BALL_SIZE) {
ballVelocity.x = -1 * abs(ballVelocity.x);
}
// Top Edge
if (ball.frame.origin.y <= 0) {
ballVelocity.y = abs(ballVelocity.y);
}
// Bottom Edge
if (ball.frame.origin.y >= VIEW_HEIGHT - BALL_SIZE) {
ballVelocity.y = -1 * abs(ballVelocity.y);
}
}
- (void) updateModelWithTime:(CFTimeInterval) timestamp {
if (lastTime == 0.0) {
// initialize lastTime if first time through
lastTime = timestamp;
} else {
// Calculate time elapsed since last call
timeDelta = timestamp - lastTime;
// Update the lastTime
lastTime = timestamp;
[self checkCollisionWithScreenEdges];
// Calculate the new position of the ball
CGFloat x = ball.frame.origin.x + ballVelocity.x * timeDelta;
CGFloat y = ball.frame.origin.y + ballVelocity.y * timeDelta;
ball.frame = CGRectMake(x, y, BALL_SIZE, BALL_SIZE);
}
}
View实施文件如下:
#import "TestView.h"
@implementation TestView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect) rect {
}
@end
最后,我的View Controller:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
gameModel = [[TestModel alloc] init];
[self.view addSubview:gameModel.ball];
// Set up the CADisplayLink for the animation
gameTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateDisplay:)];
// Add the display link to the current run loop
[gameTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void) updateDisplay:(CADisplayLink *) sender {
[gameModel updateModelWithTime:sender.timestamp];
}
好的,现在我已经看过代码的结构(希望我已经给了足够的)我可以回答我的问题。因此,当我向drawRect添加任何内容时,将绘制一个新对象,并且不会被模型逻辑方法“动画化”。
现在我有一个弹跳方块。当我尝试在drawRect中用椭圆填充正方形时,我得到一个新对象,绘制我想要的,只是在0,0处,而弹跳方块仍处于活动状态。
我确定我错过了一些非常大的东西,但是我一直在撞墙几个小时,无法弄明白。任何帮助将不胜感激!
答案 0 :(得分:0)
这里有几件事:
1-您是否将SB中的视图类重写为TestView?
2-查看代码,我看不到您的模型是如何通过控制器连接到View的。回想一下MVC模型,控制器位于顶部并向下看(金字塔样式)模型和视图等等,在视图控制器中的某处:
a)您需要实例化您的模型
b)从模型中获取值并将它们传递给视图变量 - 这将在drawrect中调用
最后但并非最不重要的是,查找setNeedsDisplay,这是调用和刷新视图的方法。
希望这有助于不破坏作业。