NSSplitViewItem - анимация свертывания и конфликт оконного набора.
Я пытаюсь сделать (новый в 10.10) NSSplitViewItem сворачиваться и разворачиваться при перемещении содержащего его окна, чтобы сохранить все это "на месте".
Проблема в том, что у меня дергается анимация (как видно здесь).
Код, где я делаю свертывание:
func togglePanel(panelID: Int) {
if let splitViewItem = self.splitViewItems[panelID] as? NSSplitViewItem {
// Toggle the collapsed state
NSAnimationContext.runAnimationGroup({ context in
// special case for the left panel
if panelID == 0 {
var windowFrame = self.view.window.frame
let panelWidth = splitViewItem.viewController.view.frame.width
if splitViewItem.collapsed {
windowFrame.origin.x -= panelWidth
windowFrame.size.width += panelWidth
} else {
windowFrame.origin.x += panelWidth
windowFrame.size.width -= panelWidth
}
self.view.window.animator().setFrame(windowFrame, display: true)
}
splitViewItem.animator().collapsed = !splitViewItem.collapsed
}, completionHandler: nil)
}
}
Мне известна проблема "Не пересекать потоки" (из сеанса 213, WWDC'13), когда анимация изменения размера окна, работающая в главном потоке, и анимация свертывания основной анимации, работающая в отдельном потоке, мешают друг другу. Помещение анимации коллапса splitViewItem в основной поток кажется неправильным подходом, и у меня возникает неприятное ощущение, что есть гораздо лучший способ сделать это, которого я пропускаю.
Поскольку нигде (пока) я не нахожу никакой документации по NSSplitViewItems, я был бы признателен за любую информацию по этому вопросу.
У меня есть небольшой тестовый проект на GitHub, если кто-то хочет посмотреть.
Обновление Упомянутый проект был обновлен с помощью решения.
Спасибо, Тео
2 ответа
Проблема похожа на проблему "не пересекать потоки" в том, что для созданной вами анимации есть два драйвера: (1) элемент разделенного вида (2) окна, и они не синхронизированы.
В примере из выступления 13 "Какао-анимация" были установлены ограничения, чтобы обеспечить правильную анимацию внутри окна, поскольку анимировался только кадр окна.
Нечто подобное можно попробовать здесь - только анимация рамки окна, а не разделение элемента представления, но, поскольку элемент управляет ограничениями, используемыми для (не) свертывания, приложение не может точно контролировать, как анимируется содержимое в окне:
Вместо этого анимация элемента разделенного вида может полностью управлять анимацией и использовать NSWindow's -anchorAttributeForOrientation:
чтобы описать, как влияет рамка окна.
if let splitViewItem = self.splitViewItems[panelID] as? NSSplitViewItem {
let window = self.view.window
if panelID == 0 {
// The Trailing edge of the window is "anchored", alternatively it could be the Right edge
window.setAnchorAttribute(.Trailing, forOrientation:.Horizontal)
}
splitViewItem.animator().collapsed = !splitViewItem.collapsed
}
Для тех, кто использует Цель C и нацелен на 10.11 El Capitan. Это помогло мне, не нужно было устанавливать AnchorAttributes.
splitViewItem.collapsed = YES;