Предпосылки и цель
У меня есть окно и три отдельных представления в файле пера в IB. Эти три представления используются для трех «частей» программы: в первом пользователь отбрасывает файл, во втором он выбирает некоторые параметры, а в третьем отображается индикатор выполнения, когда программа выполняет задачу.
Я хочу анимировать эти представления по мере их изменения, и я делаю анимацию постепенного появления / исчезновения. Цель состоит в том, чтобы старый вид (тот, который собирается исчезнуть) исчезнет по мере появления нового вида. Виды имеют разные размеры, поэтому я одновременно анимирую рамку окна (эти представления заполняют окно). Все три представления имеют базовую анимацию, включенную в IB, но ничего больше (например, представление содержимого окна) не имеет.
Код
В начале программы я регистрирую размеры представлений, чтобы использовать их позже, добавляю представления в окно и устанавливаю 2-е и 3-е представление скрытыми.
- (void)awakeFromNib
{
// Register native views' size (when they get displayed again the window can be set to their bounds)
view1NativeSize = [firstView bounds].size;
view2NativeSize = [secondView bounds].size;
view3NativeSize = [thirdView bounds].size;
// Add views to the main window's content view
NSRect viewFrame = [[mainWindow contentView] bounds];
[firstView setFrame: viewFrame];
[secondView setFrame: viewFrame];
[thirdView setFrame: viewFrame];
[[mainWindow contentView] addSubview: firstView];
[[mainWindow contentView] addSubview: secondView];
[[mainWindow contentView] addSubview: thirdView];
// Set their attributes
[secondView setHidden: TRUE];
[thirdView setHidden: TRUE];
currView = 1;
}
Затем у меня есть три метода переключения между представлениями, где я вычисляю новый оконный фрейм и вызываю метод для анимации.
- (IBAction)goToFirstView: (id)sender
{
NSRect newFrame = [mainWindow frame];
newFrame.size = view1NativeSize;
newFrame.size.height += [self titleBarHeight]; // Method that returns the title bar height
if (currView == 1) {
return;
}
else if (currView == 2) {
[self animateFromView: secondView toView: firstView andWindowFrame: newFrame];
currView--;
}
else if (currView == 3) {
[self animateFromView: thirdView toView: firstView andWindowFrame: newFrame];
currView -= 2;
}
}
- (IBAction)goToSecondView: (id)sender
{
NSRect newFrame = [mainWindow frame];
newFrame.size = view2NativeSize;
newFrame.size.height += [self titleBarHeight];
if (currView == 2) {
return;
}
else if (currView == 1) {
[self animateFromView: firstView toView: secondView andWindowFrame: newFrame];
currView++;
}
else if (currView == 3) {
[self animateFromView: thirdView toView: secondView andWindowFrame: newFrame];
currView--;
}
}
- (IBAction)goToThirdView: (id)sender
{
NSRect newFrame = [mainWindow frame];
newFrame.size = view3NativeSize;
newFrame.size.height += [self titleBarHeight];
if (currView == 3) {
return;
}
else if (currView == 1) {
[self animateFromView: firstView toView: thirdView andWindowFrame: newFrame];
currView += 2;
}
else if (currView == 2) {
[self animateFromView: secondView toView: thirdView andWindowFrame: newFrame];
currView++;
}
}
Метод анимации довольно прост. Я оживляю виды.
- (void)animateFromView: (NSView*)oldView
toView: (NSView*)newView
andWindowFrame: (NSRect)newWindowFrame
{
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration: 0.5];
[[newView animator] setHidden: FALSE];
[[oldView animator] setHidden: TRUE];
//[[mainWindow animator] setFrame: newWindowFrame]; --Doesn't work??
[NSAnimationContext endGrouping];
[mainWindow setFrame: newWindowFrame display: YES animate: YES];
}
Вопросы
У меня с этим две проблемы (сначала самая важная):
На третьем экране есть индикатор прогресса, и он никогда не отображается правильно. Не обновляется! Я вызываю -startAnimation: но она вообще не двигается. Если я отключу CA на этом третьем слое, он не исчезнет / исчезнет правильно, но индикатор выполнения начнет работать (анимировать). Понятия не имею, почему ...
В своих многочисленных экспериментах, пытающихся решить первую проблему, я пытался включить CA для представления содержимого окна и выключить CA для трех подпредставлений. Первая проблема не была решена, но я кое-что заметил: таким образом старое представление исчезало по мере того, как исчезало новое представление, тогда как до этого изменения (подпредставления с CA) я мог только замечать исчезновение нового представления. Я записал его и смотрел это в sloooowww-moootion :) и обнаружил, что был прав: старый вид волшебным образом исчезает, и все, что я вижу, это исчезает новый вид. Забавно, я обнаружил, что только после просмотра анимации я действительно хотел. Должен ли я включать CA только для представления содержимого или для всех трех подпредставлений по отдельности? (или эта проблема от чего-то другого?)
Я пробовал много чего, например, включил CA для индикатора выполнения. Я также нашел здесь много вопросов, которые близки к этому, но не касаются конкретно проблемы с индикатором выполнения.
Удачи в поиске решения :)