我正在尝试通过缩放条形(滑块)和翻译endcap来创建动画条形图。 endcap按预期工作,但是,当我尝试水平缩放时,“滑块”会转换。
-(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];
}
答案 0 :(得分:0)
好的 - 我找到了一个很好的参考资料,用于解释允许我修复代码的问题。基本上,由于缩放是基于视图的中心属性,因此它会转换原点。因此,您必须(重新)将视图转换为您希望转换的位置,作为缩放移动位置的平移距离的比率。
Demystifying CGAffineTransform
下面是我的代码(有效),您会注意到前后宽度比率的计算,然后按该数量进行平移。查看sx
的计算和tx
的第二次计算(动画之后)。我认为两者都应该放在动画中,但如果第二次翻译在开始/提交中,那么这不会像你期望的那样工作。
另请注意:我留下了一些化妆品代码,用于在栏顶显示彩色标题。
-
(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];
}