2013-08-19 3 views
1

У меня есть стандартный NSWindow с панелью инструментов. Одним из элементов панели инструментов является пользовательский вид - в частности, NSTextField. (Более конкретно, это приложение таймера - элементы управления таймера, а также цифровой дисплей находятся на панели инструментов, а другие вещи находятся в области содержимого окна. NSTextField - это цифровой дисплей.)Какао: обновлять представления за пределами представления содержимого NSWindow при изменении размера окна в реальном времени?

Обычно, я просто обновлять таймер каждую секунду, изменяя свойство «stringValue» NSTextField, что заставляет его обновлять себя. Но во время изменения живого окна, несмотря на то, что выполняется код, обновляющий свойство «stringValue» (который я проверил с NSLog), NSTextField не нарисовывается снова, пока не будет изменено размер окна. Между тем, материал внутри области содержимого полностью обновляет.

Я пробовал все способы, которыми я знаю, чтобы сообщить NSTextField, чтобы нарисовать себя, но он просто отказывается до тех пор, пока живое изменение размера не будет выполнено. Есть идеи? Очевидно, что это должно быть возможно, так как панель инструментов будет изменяться вместе с остальной частью окна - так что вы могли бы подумать, что можно заставить ее перерисовать один или несколько своих subviews, когда они перемещают их. Я предполагаю, что я могу взломать это вместе subclassingчто-то, но мой Cocoa-fu еще недостаточно силен, чтобы выяснить самый простой/самый правильный способ сделать это.

Заранее спасибо ...

EDIT: Я вроде понял, решение - это не большой, но он в основном работает на данный момент. Это в моих комментариях ниже.

+0

Вы не упоминаете, как ваш триггер таймер. Вы пытались помещать код в фоновый поток? – trojanfoe

+0

Попробуйте настроить делегат, когда NSWindow измените размер и сообщите 'NSTextField', чтобы перерисовать себя с помощью' setNeedsDisplay: 'или что-то еще. Если это не работает, то да, это, вероятно, проблема с потоком. – TheAmateurProgrammer

+0

@trojanfoe (Повторяю мой предыдущий комментарий на случай, если вы захотите продолжить, поскольку я забыл пометить вас в первый раз ... извините, новичок в Stack Overflow.) Таймер запускается каждую секунду. Что он делает даже при изменении размера окна. Проблема в том, что когда я обновляю содержимое представления в ответ на таймер, изменения фактически не набираются до тех пор, пока не будет выполнено изменение живого изображения. Я надеюсь, что если не удастся справиться с дополнительными потоками ... если это единственное решение, я просто займусь отсутствием обновления во время изменения размера, что раздражает, но не является разбойником. – Matt

ответ

0

Просто введите -[NSWindow displayIfNeeded] после того, как это будет показано на дисплее. Я столкнулся с этой проблемой при внедрении драйвера Mac для Wine (проект с открытым исходным кодом для запуска программного обеспечения Windows на OS X и других Unix-подобных операционных системах).
http://source.winehq.org/source/dlls/winemac.drv/cocoa_window.m?v=wine-1.7.11#L1905

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

+0

Если только одно представление является проблемой, почему бы не вызвать '- [NSView displayIfNeeded]'? (Я понимаю, что это может быть неприемлемо в случае вина.) – JWWalker

+0

@JWWalker, конечно, должно быть хорошо, хотя эффекты будут похожими, даже с точки зрения эффективности. Метод 'NSWindow' будет отображать только те части своей иерархии представлений, которые ему нужны. И метод NSView будет подниматься по иерархии, чтобы найти непрозрачного предка. –