Анимация изменения размера NSButton при изменении свойства imagePosition

У меня есть подкласс NSButton в среде автомакета. Подкласс реализует методы mouseEntered: и mouseExited:, которые должны изменить положение изображения кнопки. На mouseEntered: он изменяется на NSImageLeft (показ заголовка) и на mouseExited: он изменяется на NSImageOnly (не показывает заголовок).

Autolayout заботится об изменении размера подкласса NSButton в моей иерархии представлений, но он не выглядит гладким, поскольку не использует CoreAnimation для изменения размера ширины кнопки в зависимости от того, должен ли отображаться заголовок или нет. Как я могу изменить размер анимации?


person Fabian Jäger    schedule 06.08.2014    source источник


Ответы (2)


Откройте группу анимации, включите неявную анимацию, измените положение изображения кнопки, а затем принудительно выполните макет:

[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
    context.allowsImplicitAnimation = YES;
    button.imagePosition = NSImageOnly;
    [button.window layoutIfNeeded];
} completionHandler:nil];
person Ken Thomases    schedule 06.08.2014
comment
Если я добавлю этот фрагмент кода к обоим методам (mouseEntered: и mouseExited:), он все равно не анимируется, а просто сразу меняет ширину кнопки. - person Fabian Jäger; 07.08.2014
comment
Попробуйте button.animator.imagePosition = NSImageOnly;. - person Ken Thomases; 07.08.2014
comment
Я тоже так пробовал, но анимации все равно нет. Ширина меняется сразу. - person Fabian Jäger; 07.08.2014
comment
Я только что протестировал свой исходный код, используя Xcode 5.1 и OS X 10.9.4. Оно работает. Рамка кнопки анимируется между двумя размерами. (Внутренняя часть кнопки сразу меняется независимо от того, рисуется она вместе с заголовком или нет, из-за чего изображение немного прыгает.) Возможно, вы окружили код другой группой анимации, продолжительность которой была установлена ​​на 0? Что произойдет, если вы явно установите context.duration = 0.25 вверху блока? - person Ken Thomases; 07.08.2014
comment
Это может зависеть от остальной части конфигурации автоматического макета. Я добавил свое собственное решение проблемы в качестве альтернативного ответа. В моем подходе я изменил ограничение напрямую. - person Fabian Jäger; 07.08.2014

Я решил это, используя следующие методы:

- (void)mouseEntered:(NSEvent *)theEvent {
    NSSize titleStringSize = [self.title sizeWithAttributes:@{NSFontAttributeName:[NSFont     boldSystemFontOfSize:11.0]}];
    self.widthConstraint.animator.constant = titleStringSize.width+self.originalWidth+5.0;
}

- (void)mouseExited:(NSEvent *)theEvent {
    self.widthConstraint.animator.constant = self.originalWidth;
}

originalWidth и widthConstraint — это свойства моего подкласса NSButton, определенные во время awakeFromNib.

person Fabian Jäger    schedule 07.08.2014