NSAnimationContext не анимирует размер кадра для NSButton
С помощью NSAnimationContext.runAnimationGroup(_:_:)
как показано в NSAnimationContext
документация для анимации как начала, так и размера кадра работает, как ожидается, для некоторых типов представлений (включая NSImageView
). Тем не менее, он не работает, как ожидается, для NSButton
если я не добавлю явное изменение размера кадра после анимации
Размер кадра анимации дляNSImageView
Следующее работает, как и ожидалось, для NSImageView. Размер перемещен в начало координат и уменьшен до 200x200:
NSAnimationContext.runAnimationGroup({(let context) -> Void in
context.duration = 2.0
// Get the animator for an NSImageView
let a = self.theImage.animator()
// Move and resize the NSImageView
a.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
}) {
print("Animation done")
}
Размер кадра анимации дляNSButton
При выполнении того же самого с NSButton, кнопка будет перемещаться, но не изменяет размер:
NSAnimationContext.runAnimationGroup({(let context) -> Void in
context.duration = 2.0
// Get the animator for an NSButton
let a = self.button.animator()
// Move and resize the NSImageView
a.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
}) {
print("Animation done")
}
Однако, если я добавлю следующую строку кода в конец, после всего кода анимации, он будет работать как положено!
self.button.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
Финальный, рабочий листинг для NSButton
является:
NSAnimationContext.runAnimationGroup({(let context) -> Void in
context.duration = 2.0
// Get the animator for an NSButton
let a = self.button.animator()
// Move and resize the NSImageView
a.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
}) {
print("Animation done")
}
self.button.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
Я не смотрю здесь в подарок, но я не понимаю, почему это требуется для NSButton, или даже что заставляет его работать. Может кто-нибудь объяснить, почему явно установить рамку NSButton
после анимации код заставляет анимацию работать?
1 ответ
Я подозреваю, что это как-то связано с неявными ограничениями автопоставки, которые генерируются во время выполнения. После изменения фрейма, автоматическая разметка просто возвращает его к исходному размеру.
Я отказался от первоначального подхода в пользу следующего:
- Создайте ограничения ширины и / или высоты в Интерфейсном Разработчике. Я использую приоритет по умолчанию 1000 (ограничение обязательно).
- Создайте выход для ширины и / или высоты
NSLayoutConstraint
, Это было сложно в IB: мне пришлось дважды щелкнуть ограничение на вкладке измерений инспектора, после чего был открыт объект ограничения в инспекторе. Затем вы можете выбрать вкладку подключения и подключить розетку. - В моем
NSViewController
Подкласс Я использую якоря, чтобы определить новую высоту или ширину:theWidthConstraint.constant = 200
с последующимself.view.needsUpdateConstraints = true
Этот подход намного чище и более совместим с системой автоматического размещения. Кроме того, это позволяет легко анимировать все изменения макета, возникающие в результате новой автоматической раскладки:
NSAnimationContext.runAnimationGroup({(let context) -> Void in
context.duration = 1.0
self.theWidthConstraint.animator().constant = 200
// Other constraint modifications can go here
}) {
print("Animation done")
}