#macos #animation #cocoa #calayer #nsbutton
#macos #Анимация #какао #calayer #nsbutton
Вопрос:
У меня есть square
NSButton
набор, использующий автоматическую компоновку в раскадровке. Кнопка установлена как Image only
, и я использую NSRefreshTemplate
системный образ.
Это мой код, чтобы заставить его вращаться
static BOOL _animate = NO;
- (void)animateRefreshButton:(BOOL)animate
{
NSButton *btn = _refreshButton;
[btn setWantsLayer:YES];
// Set the anchor point of the refresh button
CALayer *btnLayer = btn.layer;
NSRect frame = btn.frame;
btnLayer.position = NSMakePoint(NSMidX(frame), NSMidY(frame)); // position to centre of frame
btnLayer.anchorPoint = NSMakePoint(0.5, 0.5); // anchor point to centre - specified in unit coordinates
_animate = animate;
if (animate)
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.delegate = self;
animation.fromValue = [NSNumber numberWithFloat:2 * M_PI];
animation.toValue = [NSNumber numberWithFloat:0];
animation.duration = 0.6; // Speed
animation.repeatCount = 1;// INFINITY; // Repeat forever. Can be a finite number.
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[btn.layer addAnimation:animation forKey:@"refreshbutton.rotation"];
}
}
Это работало нормально, пока я не запустил новую Xcode 12.2
бета MacOS 11.0
-версию. Теперь вращение кнопок, похоже, не является центральным.
Если я установлю кнопку Scaling
None
, она будет вращаться по центру нормально, но изображение слишком маленькое. Если я установлю Scaling
Proportionately Up or Down
значение, чтобы изображение заполняло кнопку, оно странно вращается.
Как я могу это исправить?
Комментарии:
1. Почему вы устанавливаете точку привязки на
0.5
, не0.0
будет центром?2. 0,5 — это центр developer.apple.com/documentation/quartzcore/calayer /…
3. Теперь я это вижу, спасибо; что произойдет, если вы попытаетесь установить рамку фиксированного размера? (например.
NSRect frame = CGRect(x: 0, y: 0, width: 20, height: 20
)?4. Я посмотрю. Я начинаю думать, что это новая ошибка.
5. Так обстоит дело с бета-версиями, или они что-то изменили, и это не очевидно.
Ответ №1:
Проблема
На Каталине он все еще работает даже с бета-версией Xcode 12. Проблема, похоже, в том, что в macOS 11 Big Sur кнопка больше не выровнена по центру.
Это можно протестировать следующим образом:
button.image = [NSImage imageNamed:NSImageNameRefreshTemplate];
[button.cell setBackgroundColor:NSColor.redColor];
Это отличается от Catalina, где кнопка выровнена по центру. Возможно, это ошибка в Big Sur, которая будет исправлена в следующей версии. Для обоих вариантов я использовал Xcode 12.2 beta 2. Таким образом, это связано с ОС, а не с бета-версией Xcode.
Обходной путь
Нарисуйте значок обновления по центру и используйте свой собственный значок, например
button.image = [NSImage imageNamed:@"my_refresh_icon"];
Тогда анимация работает так же хорошо на Catalina, как и на macOS Big Sur.
Тест
Комментарии:
1. Отличный ответ, спасибо. Вы говорите, что нужно нарисовать изображение нужного размера, чтобы кнопке не нужно было его выравнивать, или просто изображение системы не центрировано?
2. В Big Sur этот
NSImageNameRefreshTemplate
системный значок на кнопке, по крайней мере, неправильно отцентрирован (по какой-либо причине), см. Расстояние до нижней границы кнопки, как вы можете видеть на первом скриншоте Big Sur. Поэтому, если кнопка вращается вокруг центра (красная прямоугольная область), это дает эффект, который вы показываете в своем вопросе.3. Круглая часть значка, которую я нарисовал, полностью центрирована. Визуально это не очевидно на первый взгляд из-за стрелки, но я использовал рекомендации для построения. Сам символ, конечно, можно было бы создать немного более тщательно, только для целей тестирования, для продуктивного использования я бы предпочел использовать PDF, а не PNG. Вот ссылка на символ, если это полезно: software7.biz/iertzzlmckljkjlmrls/my_refresh_icon.png
4. Спасибо, что нашли время разобраться в этом. Похоже, проблема связана с
NSImageNameRefreshTemplate
изображением, поскольку использование моего собственного изображения работает нормально.