2011-12-17 68 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! 
}