簡體   English   中英

Quartz 2D MVC工程圖

[英]Quartz 2D MVC Drawing

所有。 我正在嘗試遵循在iPhone屏幕上彈起球的教程。 本教程以MVC方案構造應用程序。 當涉及到View實現中的drawRect方法時,我很難理解這個概念。

這是我的模型頭文件:

#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處。

我確定我在這里錯過了一些非常重要的事情,但是我已經將頭部撞在牆上好幾個小時了,無法弄清。 任何幫助將不勝感激!

這里有幾件事:

1-您是否已將SB中的視圖類重寫為TestView?
2-查看您的代碼,我看不到您的模型如何通過控制器連接到View。 從MVC模型中回想起,Controller在頂部,並與模型和視圖對話(金字塔樣式),因此在視圖控制器中的某個位置:
a)您需要實例化模型
b)從模型中獲取值並將其傳遞給視圖變量-在drawrect中將其稱為

最后但並非最不重要的一點,是查找setNeedsDisplay,它是調用和刷新視圖的方式。

希望這會有所幫助,而不會破壞任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM