Какао живое изменение размеров окна

Живое изменение размеров окна является областью, где плохо оптимизированный код для прорисовки становится особенно очевидным. Когда пользователь изменяет размеры Вашего окна, перемещение окна должно быть гладким. Если Ваш код пытается выполнить слишком много работы в это время, перемещение окна может казаться изменчивым и безразличным пользователю.

Следующие разделы представляют Вас нескольким опциям для улучшения Вашего живого кода изменения размеров. В зависимости от которых версий OS X Вы предназначаетесь, Вы могли бы использовать один или больше этих опций в Вашей реализации.

Нарисуйте минимально

То, когда живое изменяет размеры работы, происходит, скорость обязательна. Самый простой способ улучшить скорость состоит в том, чтобы выполнить меньше работы. Поскольку качество обычно менее важно во время живого, изменяют размеры работы, можно взять некоторые ярлыки для ускорения получения. Например, если Ваш код для прорисовки обычно выполняет вычисления высокой точности для определения расположения элементов, Вы могли бы заменить те вычисления быстрыми приближениями во время живого, изменяют размеры работы.

NSView обеспечивает inLiveResize метод для сообщения, когда живое изменяют размеры работы, имеет место. Можно использовать этот метод в Вашем drawRect: подпрограмма, чтобы сделать условное получение, как показано в следующем примере:

- (void) drawRect:(NSRect)rect
{
    if ([self inLiveResize])
    {
        // Draw a quick approximation
    }
    else
    {
        // Draw with full detail
    }
}

Другой способ минимизировать работу состоит в том, чтобы перерисовать только те области Вашего представления, представленные во время изменять размеры работы. При предназначении для приложения для версии 10.3 OS X можно использовать getRectsBeingDrawn:count: метод для получения представленных прямоугольников. Если Вы предназначаетесь для версии 10.4 OS X или позже, getRectsExposedDuringLiveResize:count: метод предоставлен для возврата только прямоугольников, представленных путем изменения размеров.

Живое какао изменяет размеры уведомлений

Начиная с OS X v10.1, можно использовать viewWillStartLiveResize и viewDidEndLiveResize методы NSView, чтобы помочь оптимизировать Ваше живое изменяют размеры кода. Какао сразу вызывает эти методы прежде и сразу после того, как живое изменяет размеры работы, имеет место. Можно использовать viewWillStartLiveResize метод к данным кэша или делает любую другую инициализацию, которая может помочь скорости встать, Ваши живые изменяют размеры кода. Вы используете viewDidEndLiveResize метод, чтобы очистить Ваши кэши и возвратить Ваше представление его нормальному состоянию.

Вызовы какао viewWillStartLiveResize и viewDidEndLiveResize для каждого представления в иерархии Вашего окна. Это сообщение отправляется только один раз в каждое представление. Представления, добавленные в течение середины живого, изменяют размеры работы, не получают сообщение. Точно так же при удалении представлений, прежде чем концы работы изменения размеров, те представления не получат viewDidEndLiveResize сообщение.

При использовании этих методов для создания приближения с низкой разрешающей способностью содержания, Вы могли бы хотеть лишить законной силы содержание своего представления в Вашем viewDidEndLiveResize метод. Лишение законной силы представления вызывает, это быть перерисованным в полном разрешении за пределами живого изменяет размеры цикла.

Если Вы переопределяете также viewWillStartLiveResize или viewDidEndLiveResize, удостоверьтесь, что отправили сообщение в super позволить подпредставлениям подготавливаться к изменять размеры работе также. Если необходимо добавить представления, прежде чем изменять размеры работа начнется, удостоверьтесь, что сделали так перед вызовом super если Вы хотите, чтобы то представление получило viewWillStartLiveResize сообщение.

Содержание окна заповедника

В OS X v10.4 и позже, Какао предлагает Вам, способ быть еще более умным об обновлении Вашего содержания во время живого изменяет размеры работы. И NSWindow и NSView включают поддержку сохранения содержания во время работы. Этот метод позволяет Вам решить, какое содержание действительно недопустимо и должно быть перерисовано.

Для поддержки сохранения содержания необходимо сделать следующее:

  1. Переопределите preservesContentDuringLiveResize метод в Вашем пользовательском представлении. Ваша реализация должна возвратиться YES указать, что представление поддерживает сохранение содержания.

  2. Переопределите свое представление setFrameSize: метод. Ваша реализация должна лишить законной силы любые части Вашего представления, которое должно быть перерисовано. Как правило, это включает только прямоугольные области, представленные, когда увеличился размер представления.

Для нахождения областей представления, представленных во время изменения размеров NSView обеспечивает два метода. rectPreservedDuringLiveResize метод возвращает прямоугольную область Вашего не изменявшегося представления. getRectsExposedDuringLiveResize:count: метод возвращает список прямоугольников, представляющих любые недавно представленные области. Для большинства представлений Вы должны только передать прямоугольники, возвращенные этим вторым методом к setNeedsDisplayInRect:. Первый метод предоставлен в случае, если все еще необходимо лишить законной силы остальную часть представления.

Следующий пример обеспечивает реализацию по умолчанию, которую можно использовать для Вашего setFrameSize: метод. В примере ниже, проверки реализации, чтобы видеть, изменяется ли представление. Если это, и если какие-либо прямоугольники были представлены работой изменения размеров, это получает недавно представленные прямоугольники и лишает законной силы их. Если уменьшенный размер представления, этот метод ничего не делает.

- (void) setFrameSize:(NSSize)newSize
{
    [super setFrameSize:newSize];
 
    // A change in size has required the view to be invalidated.
    if ([self inLiveResize])
    {
        NSRect rects[4];
        NSInteger count;
        [self getRectsExposedDuringLiveResize:rects count:&count];
        while (count-- > 0)
        {
            [self setNeedsDisplayInRect:rects[count]];
        }
    }
    else
    {
        [self setNeedsDisplay:YES];
    }
}