2011-12-17 95 views
6

家伙, 这是我的代码:CGContext上和视网膜显示

- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx { 
    //background 
    CGContextSetFillColorWithColor(ctx, [[UIColor colorWithRed:((float)238/255.0f) green:((float)233/255.0f) blue:((float)215/255.0f) alpha:1] CGColor]); 
    CGContextFillRect(ctx, CGRectInset(leavesView.bounds, 0, 0)); 
    //text 
    CGContextSetTextDrawingMode(ctx, kCGTextFill); 
    CGContextSetTextMatrix(ctx, CGAffineTransformMake(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)); 
    CGContextSetFillColorWithColor(ctx, [[UIColor blackColor] CGColor]); 
    UIGraphicsPushContext(ctx); 

    CGContextSaveGState(ctx); 
    CGContextTranslateCTM(ctx, 0.1f, leavesView.bounds.size.height); 
    CGContextScaleCTM(ctx, 1.0f, -1.0f); 

    CGRect textRect = CGRectMake(5, 5, leavesView.bounds.size.width-10, leavesView.bounds.size.height-10); 
    if (pages.count > 0 && pages.count-1 >= index) { 
     [[pages objectAtIndex:index] drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft]; 
    } 

    CGContextRestoreGState(ctx); 

    UIGraphicsPopContext(); 
} 

它可以完美运行在iPhone 2G,3G,3GS,但新车型我有问题。

在视网膜上的文本被绘制不是分辨率的两倍,如在标准。

你有什么想法吗?

回答

16

尝试设置层contentScale变量是这样的:

layer.contentsScale = [UIScreen mainScreen].scale; 

这应该使代码适应视网膜/ nonretina显示器。

+0

哦!你拯救了我的一天。真的不是那么明显。 – orkenstein 2014-10-01 14:15:26

+0

我已经对CALayer进行了分类,我必须在init方法中执行此操作。在drawWithContext方法中抛出一个只读错误。 – 2015-08-26 23:01:47

3

看起来你在git上使用Leaves项目。我在我的项目中遇到了同样的问题,并按如下方式解决。

首先,您需要根据设备的屏幕比例调整和缩放在ImageForPageIndex:LeavesCache.m中创建的原始Core Graphics上下文。确保也要缩放CGContextClipToRect。

- (CGImageRef) imageForPageIndex:(NSUInteger)pageIndex { 
    CGFloat scale = [[UIScreen mainScreen] scale]; // we need to size the graphics context according to the device scale 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(NULL, 
              pageSize.width*scale, 
              pageSize.height*scale, 
              8,      /* bits per component*/ 
              pageSize.width*scale * 4, /* bytes per row */ 
              colorSpace, 
              kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

    CGColorSpaceRelease(colorSpace); 
    CGContextClipToRect(context, CGRectMake(0, 0, pageSize.width*scale, pageSize.height*scale)); 

    CGContextScaleCTM(context, scale, scale); 

    [dataSource renderPageAtIndex:pageIndex inContext:context]; 

    CGImageRef image = CGBitmapContextCreateImage(context); 
    CGContextRelease(context); 

    [UIImage imageWithCGImage:image]; 
    CGImageRelease(image); 

    return image; 
} 

接下来,在LeavesView.m setUpLayers,你就需要在设备屏幕比例适用于被初始化每个CALayer的。由Brad Larson发布在similar question

默认情况下,您的CALayer不会在Retina显示屏的更高分辨率下显示其Quartz内容。在我申请的装置规模,以首页上的CALayer

layer.contentsScale = [[UIScreen mainScreen] scale]; 

因此,这里有来自LeavesView.m setUpLayers第几行:您可以启用此使用类似于下面的代码。你需要这样做是为了在setUpLayers初始化所有CALayers和CAGradientLayers:

- (void) setUpLayers { 
    // Set the backgound image of the leave view to the book page 
    UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"open_book_page_turn.png"]]; 

    self.clipsToBounds = YES; 

    topPage = [[CALayer alloc] init]; 
    topPage.contentsScale = [[UIScreen mainScreen] scale]; // We need to apply the device display scale to each layer 
    topPage.masksToBounds = YES; 
    topPage.contentsGravity = kCAGravityLeft; 
    topPage.backgroundColor = [[UIColor whiteColor] CGColor]; 
    topPage.backgroundColor = [background CGColor]; 

    ... 

} 
2

你可以只设定比例,当您启动的背景下

+ (UIImage *)imageWithView:(UIView *)view { 
    UIGraphicsBeginImageContextWithOptions([view bounds].size, NO, [[UIScreen mainScreen] scale]); 

    [[view layer] renderInContext:UIGraphicsGetCurrentContext()]; 

    UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    return result; 
} 
0

对于斯威夫特3

func getImageFromContext() -> UIImage{ 

    UIGraphicsBeginImageContextWithOptions(self.frame.size, false, UIScreen.main.scale) 
    self.drawHierarchy(in: self.bounds, afterScreenUpdates: true) 
    self.layer.render(in: UIGraphicsGetCurrentContext()!) 
    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    return image! 
}