0

全部。我正試着按照iPhone的屏幕製作球彈跳的教程。本教程在MVC方案中構建應用程序。在涉及到View實現中的drawRect方法時,我無法繞開這個概念。石英2D MVC圖

這是我的模型的頭文件:

#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); 
    } 
} 

觀實現文件如下:

#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 

最後,我的視圖控制器:

- (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

這裏有幾件事:

1-你有沒有覆蓋視圖類在SB到TestView?
2-看着你的代碼,我沒有看到你的模型如何通過你的控制器連接到你的視圖。從MVC模型中回想一下,控制器處於頂部並向下(金字塔樣式)向模型和視圖進行對話,因此,在視圖控制器中的某處:
a)您需要實例化您的模型
b)獲取值從你的模型,並將其傳遞到您的視圖變量 - 這將在drawRect中

最後但並非最不重要的,查找setNeedsDisplay這是調用並刷新視圖的方式調用。

希望這有助於不損害任務。

+0

嘿,謝謝你的回覆。我用我的View Controller實現更新了我的初始職位。 SB代表什麼? = /從我可以收集,我正確地實例化模型並添加TestView。 – 2013-02-11 13:25:03

+0

SB = Storyboard。我建議你花一些時間在CS193P MVC上(我認爲課程#1或#2)iTunes課程。在viewDIdLoad中,您正在正確地實例化模型,但不能將該模型添加爲子視圖。它不是一個UIView,它是一個模型。同樣,你的瀏覽器實例化模型,然後應該通過屬性發送信息到TestView類。 – Spectravideo328 2013-02-11 13:36:05

+0

好的,我會檢查出來的。感謝您的建議。另外,是的,我已經將視圖類更改爲SB中的TestView。 – 2013-02-11 13:48:57