#cocoa #macos #zooming #appkit
#cocoa #macos #масштабирование #appkit
Вопрос:
Как реализовать масштабирование в Cocoa AppKit-приложении (т. Е. Не увеличивать окно, а масштабировать окно и все его подвиды)? Я думаю, что в iOS это называется zoomScale. Можно ли это сделать, используя Core Animations или Quartz 2D (например CGContextScaleCTM
), или я вынужден внедрять это вручную во всех моих NSViews, NSCells и т.д.?
Ответ №1:
У каждого NSView есть границы и рамка, рамка — это прямоугольник, который описывает размещение представления в пределах границ его супервизора. Большинство представлений имеют границы с нулевым началом координат и размер, соответствующий размеру их фрейма, но это не обязательно должно быть так. Вы можете изменить соотношение границ вида и рамки для масштабирования и преобразовать как пользовательский чертеж, так и подвиды. Когда вы изменяете границы вида, это также рекурсивно влияет на отрисовку видов-потомков.
Самый простой способ изменить границы представления — с помощью -[NSView scaleUnitSquareToSize:]. В одном из ваших представлений попробуйте вызвать [self scaleUnitSquareToSize:NSMakeSize(2.0, 2.0)], и вы должны увидеть, что размер всего, что находится внутри, кажется двойным.
Вот пример. Создайте файл XIB с окном, содержащим пользовательский вид, и кнопкой. Установите для пользовательского класса пользовательского представления значение MyView. Соедините действие кнопки с действием doubleSize: в представлении. Создайте, запустите и нажмите кнопку. Красный квадрат в пользовательском представлении должен удваиваться в размере при каждом нажатии.
/// MyView.h
@interface MyView : NSView {
}
- (IBAction)doubleSize:(id)sender;
@end
/// MyView.m
@implementation MyView
- (IBAction)doubleSize:(id)sender {
[self scaleUnitSquareToSize:NSMakeSize(2.0, 2.0)];
/// Important, changing the scale doesn't invalidate the display
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)dirtyRect {
NSSize squareSize = NSMakeSize(8, 8);
NSRect square = NSMakeRect([self bounds].size.width / 2 - squareSize.width / 2,
[self bounds].size.height / 2 - squareSize.height / 2,
squareSize.width,
squareSize.height);
[[NSColor redColor] set];
NSRectFill(square);
}
@end
Комментарии:
1. Я пытаюсь заставить это работать для представления, в котором много вложенных представлений. Представление, к которому я его применяю, масштабируется, но вложенные представления остаются того же размера. Предполагается ли, что они также масштабируются?
2. Я бы ожидал, что площадь экрана, которую они занимают, изменит размер, но их отдельные прямоугольники рамки должны оставаться неизменными.
3. Что я вижу, так это то, что визуальный размер вложенных представлений остается неизменным, даже когда размер масштабируемого представления увеличивается или уменьшается.
4. Возможно ли, что тот факт, что подвиды поддерживаются слоями, будет иметь значение?
5. Я попытался отключить слои для иерархии представлений, и, действительно, изменение размера начинает выполняться лучше. У меня все еще есть ряд проблем, но я думаю, что они связаны со способом отображения моих представлений.