Использование NSProgressIndicator внутри NSMenuItem
-
10-10-2019 - |
Вопрос
Я пытаюсь использовать NSProgressIndicator (неопределенный) внутри меню в строке состояния.Я использую NSView-object в качестве представления для menuitem, а затем просматриваю индикатор выполнения, чтобы отобразить его.Но всякий раз, когда я пытаюсь вызвать startAnimation:что касается прогресса, то ничего не происходит.Когда я пытаюсь сделать то же самое в обычном NSWindow, это работает отлично, просто не внутри menuitem.
Я новичок как в cocoa, так и в objective-c, поэтому, возможно, я упустил из виду что-то "очевидное", но я довольно долго искал обходной путь, но безуспешно.Я нашел кое-что о том, что menuitems не могут обновляться при отображении и что вместо этого вам нужно использовать окно без границ.Но я не смог подтвердить это ни в какой документации.
Редактировать:
О'кей, теперь почти работает.При использовании setUsesThreadedAnimation:и из menuWillOpen MenuWelegate в MenuWelegate открывается и создается новый поток.Этот поток запускает локальный метод:
-(void) doWork(NSProgressIndicator*) p{
[p startAnimation:self];
}
Это запустит progressindicator случайным образом (?) при открытии меню.Если я позвоню startAnimation:
напрямую, не проходя через doWork:
(все еще используя новый поток), это никогда не работает.Не делает setUsesThreadedAnimation:
заставить индикатор выполнения создать собственный поток для анимации?
Решение
Решил это с помощью:
[progressIndicator performSelector:@selector(startAnimation:)
withObject:self
afterDelay:0.0
inModes:[NSArray
arrayWithObject:NSEventTrackingRunLoopMode]];
Внутри menuWillOpen: проблема, похоже, заключалась в вызове startAnimation:до того, как панель выполнения была закончена рисовать саму себя.
Другие советы
Как вы ссылаетесь на NSProgressIndicator
это в представлении (и в окне, если уж на то пошло)?Например, есть ли у вас класс контроллера, который имеет IBOutlet
подключен к индикаторам прогресса?Если вы используете IBOutlet
, вы уверены, что он правильно подключен к файлу nib?
Кроме того, куда и когда ты звонишь startAnimation:
?(Нам нужно посмотреть какой-нибудь код).
Одна вещь, которая иногда может случиться, - это то, что вы забываете подключить IBOutlet
в самом кончике.Затем, когда вы пытаетесь сообщить объекту, чтобы он что-то сделал в коде во время выполнения, IBOutlet
является nil
, и итак, то, что вы считаете сообщением, отправляемым вашему объекту, на самом деле является сообщением, отправляемым nil
.Другими словами, это просто игнорируется и фактически выглядит так, как будто это не работает.
При условии, что у вас есть (потенциально) допустимая ссылка на объект пользовательского интерфейса, другая распространенная проблема, которую вы увидите, - это когда разработчик пытается отправить сообщение объекту "слишком рано".В целом, init
методы находятся на слишком раннем этапе существования объекта контроллера, чтобы иметь возможность отправлять сообщения объектам пользовательского интерфейса — тем IBOutlet
они все еще nil
.К тому времени -awakeFromNib
называется, IBOutlet
они должны быть действительными (при условии, что вы подключили их в IB), и затем вы можете отправить сообщение объекту пользовательского интерфейса.
Вы сказали ему использовать потоковую анимацию через -setUsesThreadedAnimation:?