2014년 12월 26일 금요일

[iOS] 원형의 그라디언트 이미지를 그려봅시다. (Rendering a radial gradient)

Radial Gradient

원형으로 배경을 은은하게 채워야하는 경우에, 아래와 같이 그림이 필요합니다.
이미지를 만들어서 넣으면 좋겠지만, Core Graphics를 사용해서 그릴 수 있습니다.
만들 이미지
source code
- (void)drawRadialGradient:(UIColor *)startColor
                  endColor:(UIColor *)endColor
                startPoint:(CGPoint)startPoint
               startRadius:(CGFloat)startRadius
                  endPoint:(CGPoint)endPoint
                 endRadius:(CGFloat)endRadius
                   context:(CGContextRef)context
{
    CGColorRef colorRef = startColor.CGColor;
    CGColorRef endColorRef = endColor.CGColor;
    NSArray *marrColors=[NSArray arrayWithObjects:
                         (__bridge id)colorRef,    //start color
                         (__bridge id)endColorRef, //end color
                         nil];
    CFArrayRef colors =(__bridge CFArrayRef)(marrColors);
    CGColorSpaceRef colorSpc = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpc, colors, Nil);
    
    // generates Radial Gradient
    CGContextDrawRadialGradient(context, gradient,
                                startPoint, startRadius,
                                endPoint, endRadius,
                                0);
    CGColorSpaceRelease(colorSpc);
    CGGradientRelease(gradient);
}
 



이 함수를 이용해서, 중심에 그리면, 위 만들이미지와 같은 효과를 얻을 수 있습니다.

Drawing a radial gradient like Lens


그러면, Gradient에 이미지를 추가하면 중간에 이미지가 추가가 됩니다.
source code
- (void)drawRadialGradient:(UIColor *)startColor
                  midColor:(UIColor *)midColor
                  endColor:(UIColor *)endColor
                startPoint:(CGPoint)startPoint
               startRadius:(CGFloat)startRadius
                  endPoint:(CGPoint)endPoint
                 endRadius:(CGFloat)endRadius
                   context:(CGContextRef)context
{
    CGColorRef colorRef = startColor.CGColor;
    CGColorRef midColorRef = midColor.CGColor;
    CGColorRef endColorRef = endColor.CGColor;
    NSArray *marrColors=[NSArray arrayWithObjects:(__bridge id)colorRef,
                         (__bridge id)midColorRef,
                         (__bridge id)endColorRef, nil];
    CFArrayRef colors =(__bridge CFArrayRef)(marrColors);
    CGColorSpaceRef colorSpc = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpc, colors, Nil);
    
    // generates Radial Gradient
    CGContextDrawRadialGradient(context, gradient,
                                startPoint, startRadius,
                                endPoint, endRadius,
                                0);
    CGColorSpaceRelease(colorSpc);
    CGGradientRelease(gradient);
}
호출하는 소스
- (void)drawRect:(CGRect)rect {
    
    CGContextRef context = UIGraphicsGetCurrentContext();

    
    // Drawing code
    UIColor *whiteColor = [UIColor whiteColor];
    UIColor *blueColor = [UIColor blueColor];
    UIColor *greenColor = [UIColor greenColor];
    
    CGSize size = self.frame.size;
    CGPoint center = CGPointMake(size.width/2, size.height/2);
    /*/
    [self drawRadialGradient:greenColor endColor:self.backgroundColor
                  startPoint:center startRadius:0
                    endPoint:center endRadius:size.width/2
                     context:context];
    /*/
    [self drawRadialGradient:greenColor midColor:blueColor endColor:whiteColor
                  startPoint:center startRadius:0
                    endPoint:center endRadius:size.width/2
                     context:context];
    CGPoint point2 = CGPointMake(size.width/2-15, size.height/2-15);
    [self drawRadialGradient:whiteColor endColor:greenColor
                  startPoint:point2 startRadius:0
                    endPoint:point2 endRadius:5
                     context:context];
    point2 = CGPointMake(size.width/2+15, size.height/2+15);
    [self drawRadialGradient:whiteColor endColor:greenColor
                  startPoint:point2 startRadius:0
                    endPoint:point2 endRadius:2
                     context:context];
     //*/
}


결과물
3가지 색으로만
3가지 색에, 점 2개 찍은것


나름 랜즈와 비슷한 것이 나온것 같군요.






2014년 12월 10일 수요일

[iOS] NSString으로 된 값을 파일로 직접 저장하자.

현재 App의 디렉토리 Path를 읽어 오고, 거기에 파일 이름을 추가합니다.


 source code
- (NSURL *)urlForFilename:(NSString *)filename {
    NSFileManager *fm = [NSFileManager defaultManager];
    NSArray *urls = [fm URLsForDirectory:NSDocumentDirectory
                               inDomains:NSUserDomainMask];
    NSURL *directoryURL = urls[0];
    NSURL *fileURL = [directoryURL URLByAppendingPathComponent:filename];
    return fileURL;
}

이름을 정하고 나면, NSString에서 바로 저장합니다.


    BOOL status = [string writeToFile:[pathUrl.path stringByAppendingPathExtension:@"txt"]
                           atomically:YES 
                             encoding:NSUTF8StringEncoding 
                                error:&error];
        
    if (error != nil) {
        NSLog(@"save error: %@", [error description]);
    }
    if (status == NO) {
        NSLog(@"save error");
    }


파일로부터 데이터를 읽어 올 경우도, NSString의 카테고리를 이용합니다.

    NSString *string = [NSString stringWithContentsOfURL:pathUrl 
                                                encoding:NSUTF8StringEncoding 
                                                   error:&error];
    if (error != nil || string == nil) {
       NSLog(@"Can't load file: %@, error:%@", pathUrl.path, [error description]);
    }


만약, 문자열이 아닌 Binary데이터를 저장하려면, NSString대신, NSData의 카테고리 함수를 이용하면, 똑같이 사용이 가능합니다.