Изображения в NSImageViews случайно перевернуты - PullRequest
3 голосов
/ 21 января 2011

Итак, у меня есть странная проблема в моем приложении Какао. Элемент панели инструментов и некоторые NSImageViews просто отображают свое изображение вверх ногами без видимой причины. Элемент панели инструментов действительно появляется таким образом, когда я по какой-то причине запускаю приложение (значок назначается в коде), а затем, когда я открываю свой HUD с эффектом увеличения масштаба изображения, содержащиеся в нем imageViews перевернуты.

alt text

Это изображение выше - скриншот этого странного явления. Как видите, элемент «Показать корзину» странно вращается, каждый NSImageView в HUD, но NSImageView в NSBrowser в порядке.

Как мне отследить причину этого, а затем исправить его?

Ответы [ 2 ]

13 голосов
/ 21 января 2011

См. Замечания к выпуску для Mac OS X - Замечания к выпуску AppKit (Snow Leopard) :

Перевернутые изображения на панелях инструментов (Новое с Январь 2009 семя)

Обычная, но неправильная практика позвоните setFlipped:YES на изображение, которое вы планируете втянуть в перевернутый графический контекст. Это неверно потому что если изображение будет нарисовано позже в нормальный контекст, изображение появится вверх ногами. Однако Леопард и ранее содержал ошибка, при которой изображения NSToolbarItem (через setImage:) будет игнорировать их isFlipped свойство. SnowLeopard исправляет эту ошибку для приложений скомпилирован на SnowLeopard с 10.6 SDK; В результате некоторые изображения, которые должен был нарисовать с ног на голову в Леопард, начнет делать это, когда ваш Приложение перекомпилировано.

Если вы перекомпилируете свое приложение на SnowLeopard и узнайте, что ваш изображения элементов панели инструментов рисуют вверх ногами вниз, то это означает, что вы звонит setFlipped:YES куда-то в вашем коде. Вы должны удалить эти звонки и заменить изображение рисование методами, которые правильно обрабатывать перевернутые контексты. Увидеть обсуждение setFlipped: в этих Примечания к выпуску для дальнейшего обсуждения.

Re: setFlipped:

NSImage: устарела - [NSImage setFlipped:], добавление метода рисования который учитывает изменение контекста с WWDC 2008)

Перевернутый атрибут NSImage широко не поняли. Мы не одобряя это для SnowLeopard, и замена его типичного использования с меньшим подверженный ошибкам API.

Свойство описывает ориентацию внутренней системы координат NSImage. Так же, как супервью никогда не заботится о переворачивании его подпредставления, пользователь NSImage не должно заботиться о его переворачивании.

Типичный (некорректный) вариант использования попробуйте позвонить [image setFlipped:[[NSGraphicsContext currentContext] isFlipped]] только до рисовать, но это не достичь намеченной цели. Если вызывается перед кэшированием, затем представления заканчивают тем, что кэшировали вниз, и флип поглощается кеш. Если вызывается после кэширования, не имеет никакого эффекта - кешируется представление уже должно включить любое необходимое переключение. В первом случае, если NSImage нарисовано где-нибудь еще позже, это заканчивается вверх ногами в это место, которое также сбивает с толку, потому что ошибка и Выражение ошибки далеко друг от друга. Недостаток понимания относительно обманчивость также часто источник плохо работающего кода, в какие люди делают ненужным промежуточные буферы для обхода воспринимаемые рамки ошибок. каркас ведет себя в соответствии с дизайном, но вопреки ожиданиям, и семантика не так уж и полезна. Также сложно изменить семантика -[NSImage isFlipped], потому что много кода очень тесно зависит от текущего поведения. Вместо того, чтобы пытаться это, мы имеем устарела собственность.

Мы предоставляем простой и правильный способ рисовать изображения в перевернутом или незафиксированный контекст, который является ничьей метод, который может учитывать контекст flippedness. Мы также добавляем Параметр hints, соответствующий подсказкам в -bestRepresentationForRect:context:hints:.

- (void)drawInRect:(NSRect)dstRect fromRect:(NSRect)srcRect operation:(NSCompositingOperation)op fraction:(CGFloat)alpha respectFlipped:(BOOL)respectContextIsFlipped hints:(NSDictionary *)hints;

Передайте YES для respectFlipped, чтобы получить новое необычное поведение. Один Примечание для тех, кто понимает CTM и беспокоиться, что этот метод имеет странный взаимодействие, где изменение CTM может не иметь никакого влияния на изображение рисунок: это не тот случай. это метод ветвей поведения, основанный на [[NSGraphicsContext currentContext] isFlipped]. Модификация CTM может переверните свои оси вверх дном, но это не изменит результат -[NSGraphicsContext isFlipped]. Они полностью ортогональны.

Вторым допустимым использованием -[NSImage setFlipped:] было указать перевернутый контекст получен через -[NSImage lockFocus]. Есть случаи, например, рисование напрямую через NSLayoutManager, которые требуют перевернутый контекст. Чтобы покрыть этот случай, мы добавляем

- (void)lockFocusFlipped:(BOOL)flipped;

Это не меняет состояние само изображение, только контекст на какой фокус заблокирован. Это означает, что (0,0) вверху слева и положительный вдоль оси Y вниз в запертом контекст.

3 голосов
/ 21 января 2011

Мое предположение не в моей голове, что на изображение по ошибке было вызвано -setFlipped:YES.

...