У меня возникла фундаментальная проблема с использованием drawRect: любые советы были бы высоко оценены.Необходима помощь с 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: или в другое место? Поскольку фактическая анимация зависит от общего состояния приложения, я должен был бы вложенные операторы коммутатора, которые, если положить в 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];
}
Кроме того, чтобы сделать несколько последовательных анимации работать правильно , должен существовать внешний управляющий механизм, включающий в себя делегат анимации анимацииDidStop: обратный вызов, который бы установил потребности в записиDisplay в словарях, чтобы разрешить/запретить рисование (и анимацию).
Точка зрения, что мы сейчас находимся в том, что все это начинает выглядеть очень уродливо. Более конкретно:
- DrawRect: начинает раздуваться быстро и содержат код, который не «просто рисунок» код
- UIView необходимо неявное осведомленность о состоянии приложения
- общий процесс рисования теперь распространилась по всему три метода как минимум
И к сути этого поста: как я могу сделать это лучше? Что бы эксперты там рекомендовали с точки зрения общей структуры? Как я могу сохранить информацию о состоянии приложения из представления? Я рассматриваю эту проблему с неправильного направления. Есть ли совершенно другой подход, который я должен рассмотреть?