drawRect需要帮助:

时间:2010-03-12 17:08:38

标签: objective-c drawrect

我在使用drawRect时遇到了一个根本问题:非常感谢任何建议。

应用程序需要在不同的时间绘制各种.png图像,有时需要动画,有时则没有。

我希望坚持的设计目标是将代码放在drawRect中:非常简单和“哑” - 即只是绘图而不是其他应用程序逻辑。

要绘制图像,我使用的是UIImage的drawAtPoint:方法。由于此方法不将CGContext作为参数,因此只能在drawRect:方法中调用它。所以我有:

- (void)drawRect:(CGRect)rect {

 [firstImage drawAtPoint:CGPointMake(firstOffsetX, firstOffsetY)];

}

一张图片的所有精美和花花公子。为了绘制多个图像(随着时间的推移),我采取的方法是维护一个字典数组,每个字典包含一个图像,绘制点的位置和一个标志,以启用/抑制该图像的绘制。我随着时间的推移向数组添加字典,并通过UIView的setNeedsDisplay:方法触发绘图。使用字典数组允许我随时完全重建整个显示。 drawRect:现在变为:

- (void)drawRect:(CGRect)rect {


 for (NSMutableDictionary *imageDict in [self imageDisplayList]) {
  if ([[imageDict objectForKey:@"needsDisplay"] boolValue]) {
   [[imageDict objectForKey:@"image"] drawAtPoint:[[imageDict objectForKey:@"location"] CGPointValue]];
   [imageDict setValue:[NSNumber numberWithBool:NO] forKey:@"needsDisplay"];
  }
 }
}

还好。代码简单紧凑。动画这是我遇到问题的地方。第一个问题是我在哪里放动画代码?我把它放在UIView或UIViewController中吗?如果在UIView中,我将它放在drawRect:或其他地方吗?因为实际动画取决于应用程序的整体状态,所以我需要嵌套的switch语句,如果放在drawRect:中,它们看起来像这样:

- (void)drawRect:(CGRect)rect {

 for (NSMutableDictionary *imageDict in [self imageDisplayList]) {
  if ([[imageDict objectForKey:@"needsDisplay"] boolValue]) {

   switch ([self currentState]) {
    case STATE_1:
     switch ([[imageDict objectForKey:@"animationID"] intValue]) {
      case ANIMATE_FADE_IN:
       [self setAlpha:0.0];
       [UIView beginAnimations:[[imageDict objectForKey:@"animationID"] intValue] context:nil];
       [UIView setAnimationDelegate:self];
       [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
       [UIView setAnimationDuration:2];
       [self setAlpha:1.0];
       break;
      case ANIMATE_FADE_OUT:
       [self setAlpha:1.0];
       [UIView beginAnimations:[[imageDict objectForKey:@"animationID"] intValue] context:nil];
       [UIView setAnimationDelegate:self];
       [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
       [UIView setAnimationDuration:2];
       [self setAlpha:0.0];
       break;
      case ANIMATE_OTHER:
       // similar code here
       break;
      default:
       break;
     }
     break;
    case STATE_2:
     // similar code here
     break;
    default:
     break;
   }
   [[imageDict objectForKey:@"image"] drawAtPoint:[[imageDict objectForKey:@"location"] CGPointValue]];
   [imageDict setValue:[NSNumber numberWithBool:NO] forKey:@"needsDisplay"];
  }
 }

 [UIView commitAnimations];

}

此外,为了使多个顺序动画正常工作,需要有一个外部控制机制,涉及动画委托animationDidStop:回调,它将设置字典中的needsDisplay条目以允许/禁止绘制(和动画)。 / p>

我们现在的观点是,这一切都开始显得非常丑陋。更具体地说:

  • drawRect:快速膨胀并包含不是“只是绘制”代码的代码
  • UIView需要隐含意识到应用程序状态
  • 现在,绘图的整个过程至少分为三种方法

关于这篇文章的重点:我怎样才能做得更好?在整体结构方面,专家们会推荐什么?如何将应用程序状态信息保留在视图之外?我是从错误的方向看这个问题吗?我应该考虑一些完全不同的方法吗?

1 个答案:

答案 0 :(得分:2)