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 после кода анимации заставляет анимацию работать?


person drootang    schedule 21.09.2016    source источник


Ответы (1)


Я подозреваю, что это как-то связано с неявными ограничениями автомакета, генерируемыми во время выполнения. После изменения кадра автомакет просто возвращает его к исходному размеру.

Я отказался от исходного подхода в пользу следующего:

  1. Создайте ограничения ширины и/или высоты в Интерфейсном Разработчике. Я использую приоритет по умолчанию 1000 (ограничение обязательно).
  2. Создайте выход для ширины и/или высоты NSLayoutConstraint. Это было сложно в IB: мне пришлось дважды щелкнуть ограничение на вкладке измерений инспектора, после чего в инспекторе открылся объект ограничения. Затем вы можете выбрать вкладку соединений и подключить розетку.
  3. В моем подклассе 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")
}
person drootang    schedule 23.09.2016