Это привело меня в сумасшествие. У меня большое изображение, и мне нужно иметь вид, который можно масштабировать и прокручивать (в идеале он также должен быть способен вращаться, но я отказался на этой части). Поскольку изображение очень велико, я планирую использовать CATiledLayer, но я просто не могу заставить его работать. Мои требования:CATiledLayers on OS X
Мне нужно, чтобы иметь возможность увеличить (по центру мыши) и панорамирование
Изображение не должно изменять его ширину: соотношение высоты (не следует изменять размеры, только масштаб) ,
Это должно работать на Mac OS 10.9 (НЕ IOS!)
использование памяти не должно быть огромным (хотя до нравится 100 МБ должно быть в порядке).
У меня есть необходимое изображение, полное в одном файле, а также разбитое на многие (даже для разных уровней масштабирования). Я предпочитаю использовать плитки, поскольку это должно быть проще в памяти, но доступны оба варианта.
Большинство примеров в Интернете относятся к iOS и, таким образом, используют UIScrollView для масштабирования/панорамирования, но я не могу скопировать это поведение для NSScrollView. Единственным примером для Mac OS XI является this, но его масштабирование всегда идет в левом нижнем углу, а не в середине, и когда я адаптирую код для использования файлов png вместо pdf, использование памяти составляет около 400 МБ ...
Это мой лучший попробовать до сих пор:
@implementation MyView{
CATiledLayer *tiledLayer;
}
-(void)awakeFromNib{
NSLog(@"Es geht los");
tiledLayer = [CATiledLayer layer];
// set up this view & its layer
self.wantsLayer = YES;
self.layer = [CALayer layer];
self.layer.masksToBounds = YES;
self.layer.backgroundColor = CGColorGetConstantColor(kCGColorWhite);
// set up the tiled layer
tiledLayer.delegate = self;
tiledLayer.levelsOfDetail = 4;
tiledLayer.levelsOfDetailBias = 5;
tiledLayer.anchorPoint = CGPointZero;
tiledLayer.bounds = CGRectMake(0.0f, 0.0f, 41*256, 22*256);
tiledLayer.autoresizingMask = kCALayerNotSizable;
tiledLayer.tileSize = CGSizeMake(256, 256);
self.frame = CGRectMake(0.0f, 0.0f, 41*256, 22*256);
self.layer = tiledLayer;
//[self.layer addSublayer:tiledLayer];
[tiledLayer setNeedsDisplay];
}
-(void)drawRect:(NSRect)dirtyRect{
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
CGFloat scale = CGContextGetCTM(context).a;
CGSize tileSize = tiledLayer.tileSize;
tileSize.width /= scale;
tileSize.height /= scale;
// calculate the rows and columns of tiles that intersect the rect we have been asked to draw
int firstCol = floorf(CGRectGetMinX(dirtyRect)/tileSize.width);
int lastCol = floorf((CGRectGetMaxX(dirtyRect)-1)/tileSize.width);
int firstRow = floorf(CGRectGetMinY(dirtyRect)/tileSize.height);
int lastRow = floorf((CGRectGetMaxY(dirtyRect)-1)/tileSize.height);
for (int row = firstRow; row <= lastRow; row++) {
for (int col = firstCol; col <= lastCol; col++) {
NSImage *tile = [self tileForScale:scale row:row col:col];
CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row,
tileSize.width, tileSize.height);
// if the tile would stick outside of our bounds, we need to truncate it so as
// to avoid stretching out the partial tiles at the right and bottom edges
tileRect = CGRectIntersection(self.bounds, tileRect);
[tile drawInRect:tileRect];
}
}
}
-(BOOL)isFlipped{
return YES;
}
но это деформирует изображение, а не увеличить или сковороду правильно (но, по крайней мере, выбор плитки работает) ...
I не могу поверить, что это так сложно, любая помощь будет очень признательна. Спасибо :)