iPad:如何使用CGAffineTransformScale创建动态条形图?

iPad:如何使用CGAffineTransformScale创建动态条形图?,ipad,bar-chart,cgaffinetransformscale,Ipad,Bar Chart,Cgaffinetransformscale,我试图通过缩放条形图(滑块)和平移收头来创建动画条形图。收头按预期工作,但是,当我尝试水平缩放时,“滑块”会平移 -(void) animateBarOpen: (NSInteger) rowIndex { NSLog(@"%s: row=%d %@", __FUNCTION__, rowIndex, [self.values objectAtIndex:rowIndex]); NSMutableDictionary *row = [self.values objectAtInd

我试图通过缩放条形图(滑块)和平移收头来创建动画条形图。收头按预期工作,但是,当我尝试水平缩放时,“滑块”会平移

-(void) animateBarOpen: (NSInteger) rowIndex {
    NSLog(@"%s: row=%d %@", __FUNCTION__, rowIndex, [self.values objectAtIndex:rowIndex]);
    NSMutableDictionary *row = [self.values objectAtIndex:rowIndex];
    UIImageView *slider = [row objectForKey:@"slider"];
    UIImageView *endCap = [row objectForKey:@"image"];
    UILabel *labelInfo = [row objectForKey:@"label"];
    [labelInfo setText: [NSString stringWithFormat: @"%@ %@", [row objectForKey:@"quantity"], [row objectForKey:@"color"]]];
    [labelInfo setTextColor: productColor];

    float quantity = [(NSNumber*) [row objectForKey:@"quantity"] floatValue];
    float tx = 10.0f * quantity;
    float sx = -40.0f * quantity;

    [UIView beginAnimations:@"open" context:nil];
    [UIView setAnimationDuration:0.25];
    [UIView setAnimationDelay:0.0];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

    slider.transform = CGAffineTransformScale(CGAffineTransformIdentity, sx, 1.0f);

    endCap.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, tx, 0.0f);
    labelInfo.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, tx, 0.0f);

    [UIView commitAnimations];
}

好的-我找到了一个很好的参考来解释允许我修复代码的问题。基本上,由于缩放基于视图的“中心”属性,因此它会转换原点。因此,您必须(重新)将视图平移到您希望平移的位置,该位置与缩放移动的位置的平移距离成比例

下面是我的代码(有效),您会注意到,计算了前后的宽度比,然后按该值进行翻译。查看
sx
的计算和
tx
的第二次计算(动画之后)。我认为两者都应该出现在动画中,但是如果第二个翻译在begin/commit中,那么这并不像您预期的那样有效

另请注意:我留下了一些装饰性代码,用于在工具栏顶端显示彩色标题

-

(void) animateBarOpen: (NSInteger) rowIndex withDuration: (NSTimeInterval) duration {
    if (VERBOSE_LOG) {
        NSLog(@"%s: row=%d %@", __FUNCTION__, rowIndex, [self.values objectAtIndex:rowIndex]);
    }

    NSMutableDictionary *rowValues = [self.values objectAtIndex:rowIndex];
    NSMutableDictionary *rowOutlets = [self.iboutlets objectAtIndex:rowIndex];
    UIColor *productColor = [InfographView colorByName: [rowValues objectForKey: @"color"]];
    UIImageView *slider = [rowOutlets objectForKey:@"slider"];
    UIImageView *endCap = [rowOutlets objectForKey:@"image"];
    UILabel *labelInfo = [rowOutlets objectForKey:@"label"];
    NSAssert1(labelInfo != nil, @"labelInfo is NULL??", nil);
    [labelInfo setBackgroundColor: productColor];
    // (255, 253, 208)
    UIColor *creamColor = [UIColor colorWithRed:255.0/255.0f green:253.0/255.0f blue:208.0/255.0f alpha:0.9];
    [labelInfo setTextColor: creamColor];
    if ([(NSString*)[rowValues objectForKey:@"color"] isEqualToString:@"Black"]) {
        [labelInfo setShadowColor: [UIColor grayColor]];
    } else {
        [labelInfo setShadowColor: [UIColor blackColor]];
    }
    [labelInfo setText: [NSString stringWithFormat: @"%@ %@", [rowValues objectForKey:@"quantity"], [rowValues objectForKey:@"color"]]];

    [slider setHidden:YES];
    [slider setAlpha: 0.7f];

    float rangeScale = [self computeRangeScale: self.values forWidth: CGRectGetWidth(self.frame) - MARGINS];

    slider.transform = CGAffineTransformIdentity;

    float quantity = [(NSNumber*) [rowValues objectForKey:@"quantity"] floatValue];
    float tx = rangeScale * quantity;
    float sx = tx / CGRectGetWidth(slider.frame); // (CGRectGetWidth(endCap.frame) - CGRectGetWidth(slider.frame));

    float sliderWidth = CGRectGetWidth(slider.frame);

    [slider setHidden:(rowIndex == -1)];

    [UIView beginAnimations:@"open" context:nil];
    [UIView setAnimationDuration:duration];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

    slider.transform = CGAffineTransformScale(CGAffineTransformIdentity, sx, 1.0f);
    endCap.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, tx, 0.0f);
    labelInfo.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, tx, (-rowIndex*1.0f));
    [labelInfo setAlpha:1.0];

    [UIView commitAnimations];

    tx = 1.0f * (CGRectGetWidth(slider.frame) - sliderWidth) / (sx*2.0f);      slider.transform = CGAffineTransformTranslate(slider.transform, tx, 0.0f);
    [slider setHidden:NO];

}