2012-06-08 37 views
0

我正試圖通過縮放欄(滑塊)和翻譯endcap來創建一個動畫條形圖。 Endcap按預期工作,但是,當我嘗試水平縮放時,「滑塊」會轉換。iPad:如何使用CGAffineTransformScale創建動態條形圖?

-(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

好的 - 我找到了一個很好的參考來解釋允許我修復我的代碼的問題。基本上,因爲縮放是基於視圖的中心屬性,所以它翻譯原點。因此,您必須(重新)將視圖翻譯爲您希望翻譯的位置,作爲縮放移動的位置的平移距離的比例。

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]; 

}