[Solved] Create a custom gauge with an image Objective C [closed]


One of the many solutions, given the fuzziness of the question, is to use Core Animation. The official Apple documentation is here.

Let’s outline three steps:

  • Conceptual step Define what layers (conceptually) or masks you will use, and create the images that will be imported in them
  • Definition step Define your CABasicAnimation and program the layers
  • Animation step Apply your modifications

Let’s go through the details.

Conceptual step

Let’s assume you choose to have three layers:

  • background
  • empty heart shape (for example, a nice silver line, or maybe just nothing)
  • filled heart shape (for example, a nice gem cut in the shape of a heart, or jelly, or an Apple-red-skin… ask your artist)

At this point, your artist have provided you with 6 files if you’re building for iPad. Let’s assume the following names and types.

| Name | Type|
|:-----:|:––––:|
|background.jpg| background picture for iPad Mini |
|[email protected]|background picture for iPad Retina and up |
|heartenclosure.png| heart border picture for iPad Mini |
|[email protected]|heart border picture for iPad Retina and up |
|heartbody.png| heart contents picture for iPad Mini |
|[email protected]|heart contents picture for iPad Retina and up |

Once you have these as JPG/PNG files, you import them into Xcode. Pay attention to have the Retina (and iPhone 6+), with double and triple size. You will drag and drop these into a file called Images.xcassets, which is (pretty much) your “image store”.

Definition step

The plan is to have the background be static, the heart contents be animated from the current height to the new height anytime the jauge updates, and the heart border as the top layer.

Let’s build the background image:
UIImage* backgroundImg = [UIImage imageNamed:@"background"];
and the same code will create the top picture:
UIImage* heartshapeImg = [UIImage imageNamed:@"heartenclosure"];

iOS is smart enough to select the correct image, you don’t have to pass in the JPG or @2x information. By default, the z-index of images added to the display is “latest on top”.

Once the picture is built, it looks like this on my iPhone (my apologies to the original artist).

What we’ll do, and again it’s only one of many possibilities, is create three CALayers and add them as the UIView‘s layers sublayers.
For my own sake I’ve made a heart shape based on a nice heart found with Google. In your project you’ll want the real art I was suggesting earlier 😉

The code for building the layer goes into - (void) viewDidAppear:(BOOL)animated (because at this point, the frame is already set).

Note the name being set on the heart layer, which will allow us to animate it.

UIImage* backgroundImg = [UIImage imageNamed:@”background”];
UIImage* heartImage = [UIImage imageNamed:@”Coeur”];
UIImage* heartShapeImage = [UIImage imageNamed:@”Coeurshape”];

CALayer* backgroundLayer = [CALayer layer];
backgroundLayer.contentsGravity = kCAGravityResizeAspect;
backgroundLayer.opacity = 1;
backgroundLayer.opaque = YES;
backgroundLayer.hidden = NO;
backgroundLayer.cornerRadius = 20.0;
backgroundLayer.frame = CGRectInset(self.view.layer.frame, 20, 20);
backgroundLayer.backgroundColor = [[UIColor colorWithRed:1.1 green:1 blue:0 alpha:1.0]CGColor];
backgroundLayer.contents = (__bridge id) backgroundImg.CGImage;
backgroundLayer.contentsScale = [[UIScreen mainScreen] scale];
[self.view.layer addSublayer:backgroundLayer ];

CALayer* heartLayer =[CALayer layer];
heartLayer.contentsGravity = kCAGravityResizeAspect;
heartLayer.shadowOffset = CGSizeMake(0, 3);
heartLayer.shadowRadius = 5.0;
heartLayer.shadowColor = [UIColor blackColor].CGColor;
heartLayer.shadowOpacity = 0.8;
heartLayer.frame = CGRectInset(self.view.layer.frame, 80, 200);
heartLayer.contents = (__bridge id) heartImage.CGImage;
heartLayer.contentsScale = [[UIScreen mainScreen] scale];
[heartLayer setName:@"heartLayer"];
[self.view.layer addSublayer:heartLayer];

CALayer* heartShapeLayer =[CALayer layer];
heartShapeLayer.contentsGravity = kCAGravityResizeAspect;
heartShapeLayer.frame = heartLayer.frame;
heartShapeLayer.contents = (__bridge id)(heartShapeImage.CGImage);
heartShapeLayer.contentsScale = [[UIScreen mainScreen] scale];
[self.view.layer addSublayer:heartShapeLayer];

* Animation Step*

By changing the bounds of the heartLayer using CABasicAnimation, with masks enabled: heartLayer.masksToBounds = YES; you can then show the amount of heart you wish.

In order to access your sublayer, you’ll need to use its name.
This subroutine does the trick:

- (CALayer *)findLayerByName:(NSString*) layerTagName inLayer:(CALayer*) layer{

    for (CALayer *layer in [layer sublayers]) {

        if ([[layer name] isEqualToString:layerTagName]) {
            return layer;
        }
    }

    return nil;
}

Note that, as per my earlier comment, using Swift is a good option. Ray Wenderlich’s website has a nice article about UIView animations in Swift.

8

solved Create a custom gauge with an image Objective C [closed]