2

タブバーを再作成したいのですが、この問題に遭遇しました。下の画像でわかるように、現在(右の画像)で選択されているタブバーの項目は、UITabBarの項目よりもはるかに鮮明または鮮明ではありません。左側のアイコンの周りの小さな1ポイントの境界線(方法はわかりません)と、アイコン内のグラデーションに注目してください。これは私の中で非常に目立ちます。私はすでにコアグラフィックスとコアイメージフィルターを可能なアプローチとして考えていましたが、その効果を得ることができないようです。私が欲しいものの一部である古いスレッドを見つけましたが、答えは私にはうまくいかないようで、画像のピクセルを手動でループする必要があります(それが望ましいかどうかはわかりません)。誰かが私を助けることができますか?

望ましい 現在

これは私が現在使用しているコードです。ところで、私はCore Graphicsから始めているので、間違いがあれば修正してください。

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextSaveGState(context);
    {
        /* Adjust for different coordinate systems from UIKit and Core Graphics and center the image */
        CGContextTranslateCTM(context, self.bounds.size.width/2.0 - self.image.size.width/2.0, self.bounds.size.height - self.bounds.size.height/2.0 + self.image.size.height/2.0);
        CGContextScaleCTM(context, 1.0f, -1.0f);

        CGRect rect = CGRectMake(0, 0, self.image.size.width, self.image.size.height);

        /* Add a drop shadow */
        UIColor *dropShadowColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.8f];
        CGContextSetShadowWithColor(context, CGSizeMake(0, 1), 5, dropShadowColor.CGColor);

        /* Draw the original image */
        CGContextDrawImage(context, rect, self.image.CGImage);

        /* Clip to the original image, so that we only draw the shadows on the
           inside of the image but nothing outside. */
        CGContextClipToMask(context, rect, self.image.CGImage);

        if(self.isSelected){
            /* draw background image */
            CGImageRef background = [UIImage imageNamed:@"UITabBarBlueGradient"].CGImage;
            CGContextDrawImage(context, rect, background);
        }
        else{
            /* draw background color to unselected items */
            CGColorRef backgroundColor = [UIColor colorWithRed:95/255.0 green:95/255.0 blue:95/255.0 alpha:1].CGColor;
            CGContextSetFillColorWithColor(context, backgroundColor);
            CGContextFillRect(context, rect);

            /* location of the gradient's colors */
            CGFloat locations[] = { 0.0, 1.0 };

            NSArray *colors = [NSArray arrayWithObjects:(id)[UIColor colorWithRed:1 green:1 blue:1 alpha:0].CGColor, (id)[UIColor colorWithRed:1 green:1 blue:1 alpha:0.6].CGColor, nil];

            /* create the gradient with colors and locations */
            CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,(__bridge CFArrayRef) colors, locations);
            {
                /* start and end points of the gradient */
                CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
                CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
                /* draw gradient */
                CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
            }
            CGGradientRelease(gradient);
        }
    }
    CGContextRestoreGState(context);
    CGColorSpaceRelease(colorSpace);
}
4

1 に答える 1

1

私もこれに取り組んでいます。おそらく最適化は、drawrect が呼び出されるたびに UIImage をレンダリングする代わりに、ivar に UIImage オブジェクトを保存し、UIImageView.image プロパティを更新して表示することです。

次のような「輝き」でイメージを生成しています。

(plus_icon.png は 30 x 30 の画像で、幅 4 ピクセルの十字が透明な背景に黒で全体を占めています。 プラスアイコンこれは、imageView 2 および 4 のように次のようにレンダリングされます。レンダリングされたプラス アイコン

-(UIImage *)tabBarImage{

    UIGraphicsBeginImageContext(CGSizeMake(60, 60));

    UIImage *image = [UIImage imageNamed:@"plus_icon"];

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(ctx, [[UIColor clearColor] CGColor]);
    CGContextFillRect(ctx, CGRectMake(0, 0, 60, 60));

    CGRect imageRect = CGRectMake(15, 15, 30, 30);
    CGContextDrawImage(ctx, imageRect, [image CGImage]);

    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

-(UIImage *)sourceImage{
    UIGraphicsBeginImageContext(CGSizeMake(60.0, 60.0));

    CGContextRef context = UIGraphicsGetCurrentContext();

    size_t num_locations = 2;
    CGFloat locations[2] = { 0.3, 1.0 };

    CGFloat components[8] = {NC(72), NC(122), NC(229), 1.0, NC(110), NC(202), NC(255), 1.0 };

    CGColorSpaceRef cspace;
    CGGradientRef gradient;
    cspace = CGColorSpaceCreateDeviceRGB();
    gradient = CGGradientCreateWithColorComponents (cspace, components, locations, num_locations);

    CGPoint sPoint = CGPointMake(0.0, 15.0);
    CGPoint ePoint = CGPointMake(0.0, 45.0);
    CGContextDrawLinearGradient (context, gradient, sPoint, ePoint, kCGGradientDrawsBeforeStartLocation| kCGGradientDrawsAfterEndLocation);
    CGGradientRelease(gradient);
    CGColorSpaceRelease(cspace);
    [self addShineToContext:context];

    UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();    

    return image;
}

-(void)addShineToContext:(CGContextRef) context{
    CGContextSaveGState(context);
    size_t num_locations = 2;
    CGFloat locations[2] = { 0.3, 0.7};
    CGFloat components[8] = {1.0, 1.0, 1.0, 0.8, 1.0, 1.0, 1.0, 0.0};//{0.82, 0.82, 0.82, 0.4,  0.92, 0.92, 0.92, .8 };

    CGColorSpaceRef cspace;
    CGGradientRef gradient;
    cspace = CGColorSpaceCreateDeviceRGB();
    gradient = CGGradientCreateWithColorComponents (cspace, components, locations, num_locations);

    CGPoint sPoint = CGPointMake(25.0f, 15.0);
    CGPoint ePoint = CGPointMake(35.0f, 44.0f);


    [self addShineClip:context];

    CGContextDrawLinearGradient(context, gradient, sPoint, ePoint, kCGGradientDrawsBeforeStartLocation);
//    CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);
//    CGContextFillRect(context, CGRectMake(15,15, 30, 30));

    CGColorSpaceRelease(cspace);
    CGGradientRelease(gradient);

    CGContextRestoreGState(context);

}

-(void)addShineClip:(CGContextRef)context{
    CGContextMoveToPoint(context, 15, 35);
    CGContextAddQuadCurveToPoint(context, 25, 30, 45, 28);
    CGContextAddLineToPoint(context, 45, 15);
    CGContextAddLineToPoint(context, 15, 15);
    CGContextClosePath(context);
    CGContextClip(context);
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.imageView1.image = [self compositeOverSlate:[self drawTabBarOverSourceWithBlend:kCGBlendModeSourceIn]];
    self.imageView2.image = [self compositeOverSlate:[self drawTabBarOverSourceWithBlend:kCGBlendModeDestinationIn]];
    self.imageView3.image = [self compositeOverSlate:[self drawTabBarOverSourceWithBlend:kCGBlendModeSourceAtop]];
    self.imageView4.image = [self compositeOverSlate:[self drawTabBarOverSourceWithBlend:kCGBlendModeDestinationAtop]];
}

-(UIImage *)compositeOverSlate:(UIImage *)image{
    UIGraphicsBeginImageContext(image.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGRect imageRect = CGRectMake(0, 0, 0, 0);
    imageRect.size = image.size;

    CGContextSetFillColorWithColor(ctx, [[UIColor darkGrayColor] CGColor]);

    CGContextFillRect(ctx, imageRect);
    CGContextSetShadow(ctx, CGSizeMake(-1.0, 2.0), .5);
    CGContextDrawImage(ctx, imageRect, [image CGImage]);

    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();
    return result;
}

-(UIImage *)drawTabBarOverSourceWithBlend:(CGBlendMode)blendMode{
    UIGraphicsBeginImageContext(CGSizeMake(60,60));
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGContextDrawImage(ctx, CGRectMake(0, 0, 60.0, 60.0), [[self sourceImage] CGImage]);

    CGContextSetBlendMode(ctx, blendMode);
    CGContextDrawImage(ctx, CGRectMake(0, 0, 60.0, 60.0), [[self tabBarImage] CGImage]);

    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return result;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

境界線のアウトラインはまだクラックしていませんが、クラックした場合は更新します。

于 2012-12-03T20:44:28.337 に答える