【发布时间】:2014-01-31 03:43:49
【问题描述】:
这让我发疯了。我有一个大图像,需要一个既可缩放又可滚动的视图(理想情况下它也应该能够旋转,但我已经放弃了这部分) .由于图像非常大,我打算使用 CATiledLayer,但我根本无法让它工作。 我的要求是:
我需要能够缩放(在鼠标中心)和平移
图像不应更改其宽高比(不应调整大小,仅缩放)。
这应该在 Mac OS 10.9 上运行(不是 iOS!)
内存使用量不应该很大(尽管最多 100 MB 应该没问题)。
我在一个文件中完成了必要的图像,并且还平铺了许多(甚至具有不同的缩放级别)。我更喜欢使用磁贴,因为这应该更容易记忆,但两个选项都可用。
大多数在线示例都参考 iOS,因此使用 UIScrollView 进行缩放/平移,但我无法为 NSScrollView 复制该行为。找到的 Mac OS XI 的唯一示例是 this,但他的缩放总是转到左下角,而不是中间,当我调整代码以使用 png 文件而不是 pdf 时,内存使用量大约为 400 MB。 ..
这是我迄今为止最好的尝试:
@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;
}
但这会使图像变形,并且不能正确缩放或平移(但至少平铺选择有效)......
我不敢相信这这么难,任何帮助将不胜感激。谢谢:)
【问题讨论】:
标签: objective-c macos calayer nsscrollview