Нужна помощь с drawRect: - PullRequest
1 голос
/ 12 марта 2010

У меня есть фундаментальная проблема с использованием drawRect: Любой совет будет принят с благодарностью.

Приложению необходимо рисовать различные изображения .png в разное время, иногда с анимацией, иногда без.

Цель разработки, которой я надеялся придерживаться, - создать код внутри drawRect: очень простой и «тупой», т. Е. Просто рисовать и никакой другой логики приложения.

Для рисования изображения я использую drawAtPoint: метод UIImage. Поскольку этот метод не принимает CGContext в качестве параметра, он может быть вызван только внутри метода drawRect:. Итак, у меня есть:

- (void)drawRect:(CGRect)rect {

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

}

Все отлично и модно для одного изображения. Чтобы нарисовать несколько изображений (с течением времени), я выбрал поддержку массива словарей с каждым словарем, содержащим изображение, местоположение точки для рисования и флажок для включения / отключения рисования для этого изображения. Со временем я добавляю словари в массив и запускаю рисование с помощью метода setNeedsDisplay: UIView. Использование массива словарей позволяет мне полностью реконструировать весь дисплей в любое время. 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: callback, который бы устанавливал записи needsDisplay в словарях для разрешения / подавления рисования (и анимации).

Дело в том, что мы сейчас находимся в том, что все начинает выглядеть очень некрасиво. Более конкретно:

  • drawRect: начинает быстро раздуваться и содержать код, который не просто рисует код
  • UIView нуждается в неявной осведомленности о состоянии приложения
  • общий процесс рисования теперь распределен по трем методам как минимум

И к сути этого поста: как я могу сделать это лучше? Что эксперты порекомендуют с точки зрения общей структуры? Как сохранить информацию о состоянии приложения вне поля зрения? Я смотрю на эту проблему с неправильной стороны. Есть ли какой-то совершенно другой подход, который я должен рассмотреть?

1 Ответ

2 голосов
/ 05 июня 2010
...