动画自定义视图在屏幕的一半,其中包含图像 - 突然的动画

Posted

技术标签:

【中文标题】动画自定义视图在屏幕的一半,其中包含图像 - 突然的动画【英文标题】:Animating custom view half way the screen with an image in it - abrupt animation 【发布时间】:2014-02-27 18:33:24 【问题描述】:

在我的一个观点中,我有一个底栏。轻按此视图可将临时购物车动画到屏幕的一半。现在,在临时表中没有项目的地方,我显示了一个无数据叠加层,它只是一个视图,其下方有一个空的购物车图像和文本。

问题是:当这个表格动画展开和折叠时,没有数据覆盖在动画过程中看起来不好。看起来图像也在缩小/扩大,直到临时表格视图停止动画。

因此,我尝试在此动画发生时使用临时表视图的alpha,以使其看起来不那么糟糕。但这也无济于事。最后突然闪了一下。

有什么建议吗?

self.temporaryTable.backgroundView = self.noDataOverlay;

[UIView animateWithDuration:0.5 animations:^
    self.temporaryTable.alpha = 0.5;
 completion:^(BOOL finished) 
    self.temporaryTable.alpha = 1.0;
];

这是我绘制图像的代码:

    - (void)drawRect:(CGRect)iRect scalingImage:(BOOL)iShouldScale 
        CGRect aRect = self.superview.bounds;   
        // Draw our image
        CGRect anImageRect = iRect;
        if (self.image) 
            //scale the image based on the height
            anImageRect = CGRectZero;
            anImageRect.size.height = self.image.size.height;
            anImageRect.size.width = self.image.size.width;
    #ifdef ACINTERNAL
            if (iShouldScale) 
                anImageRect = [self aspectFittedRect:anImageRect max:aRect];
             else 
                anImageRect.origin.x = (iRect.size.width/2) - (anImageRect.size.width/2);
                anImageRect.origin.y = kTopMargin;
            
    #else
            anImageRect.origin.x = (iRect.size.width/2) - (anImageRect.size.width/2);
            anImageRect.origin.y = kTopMargin;
    #endif
            if (self.shouldCenterImage)
                anImageRect.origin.y = (iRect.size.height/2) - (anImageRect.size.height/2);

            [self.image drawInRect:anImageRect];
         else 
            anImageRect.origin.y = (iRect.size.height/6);
            anImageRect.size.height = (iRect.size.height/6);
        

        // Draw our title and message
        if (self.title) 
            CGFloat aTop = anImageRect.origin.y + anImageRect.size.height + kSpacer;
            CGFloat aWidth = aRect.size.width;
            UIColor *aColor = [UIColor colorWithRed:96/256.0 green:106/256.0 blue:122/256.0 alpha:1];
            [aColor set];       
            CGRect aTextRect = CGRectMake(0, aTop, aWidth, kTitleHeight * 2);
            UIFont *aTitleFont = [UIFont boldSystemFontOfSize:kTitleFontSize];
            [self.title drawInRect:aTextRect withFont:aTitleFont lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter];

            if (self.subTitle) 
                UIFont *aSubTitleFont = [UIFont systemFontOfSize:kSubTitleFontSize];
                aTextRect = CGRectMake(0, aTop+kSpacer, aWidth, kTitleHeight);
                [self.subTitle drawInRect:aTextRect withFont:aSubTitleFont lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter];
            
        
    


- (void)addToView:(UIView *)iView 
    // setting a unique tag number here so that if the user has any other tag there should not be a conflict
    UIView *aView = [iView viewWithTag:699]; 
    if (aView) 
        [aView removeFromSuperview];
    
    self.tag = 699;
    [iView addSubview:self];



- (void)removeView 
    [super removeFromSuperview];



-(void)setViewFrame:(CGRect) iFrame 
    CGRect aRect = self.frame;
    aRect.size.width = iFrame.size.width;
    aRect.size.height = iFrame.size.height;
    self.frame = aRect;
    [self setNeedsDisplay];



- (CGRect)aspectFittedRect:(CGRect)iRect max:(CGRect)iMaxRect 
    float anOriginalAspectRatio = iRect.size.width / iRect.size.height;
    float aMaxAspectRatio = iMaxRect.size.width / iMaxRect.size.height;

    CGRect aNewRect = iMaxRect;
    if (anOriginalAspectRatio > aMaxAspectRatio)  // scale by width
        aNewRect.size.height = iMaxRect.size.width * iRect.size.height / iRect.size.width;
     else 
        aNewRect.size.width = iMaxRect.size.height  * iRect.size.width / iRect.size.height;
    
    aNewRect.origin.y =  (iMaxRect.size.height - aNewRect.size.height)/2.0;
    aNewRect.origin.x =  (iMaxRect.size.width  - aNewRect.size.width)/2.0;

    return CGRectIntegral(aNewRect);

【问题讨论】:

【参考方案1】:

这里的一种可能性是修复 original 问题,即空购物车图像随着视图动画而展开/折叠的事实。没有看到你的代码很难解决这个问题,但在我自己的代码中,我所做的是将 UIImageView 的contentMode 设置为UIViewContentModeBottom。这会导致图像保持相同的大小,即使包含它的图像视图可能会随着动画的一部分而增长和缩小。

【讨论】:

这听起来很有希望,正是我正在寻找的。让我试试这个。点赞! 显然我们没有使用 UIImageView。我们使用核心图形来绘制它。我们在核心图形中是否有 contentMode 等效项? 即使您使用的是核心图形,您也必须以某种方式将图像输入界面。如果您使用的是自定义 UIView 来绘制自己,那么答案是仍然contentMode,但详细信息将取决于您的绘图代码,您仍然没有显示。 我已经编辑了我的帖子以包含图像渲染代码。 我要做的是将drawRect 代码移动到 UIGraphicsBegin... 块中,以便您正在绘制 UIImage。正如我之前所说,将 UIImage 放入图像视图中。现在,随着视图高度的增加,它只会显示越来越多的图像。实际上,我在我的 Zotz 应用程序中这样做是为了让它看起来好像从底部升起时视图模糊了它背后的东西。【参考方案2】:

您会看到一个闪光,因为您将 alpha 设置为 0.5,然后在动画完成时将其从 0.5 设置为 1.0。只需将 alpha 动画设置为 1.0:

[UIView animateWithDuration:0.5 
                 animations:^

    self.temporaryTable.alpha = 1.0;
];

【讨论】:

试过这个。它看起来不太好,因为桌子即将上来,我可以看到它后面的景色。这是因为 alpha 正在发生变化。有没有其他方法可以避免视图内图像的扩大/缩小外观?点赞!

以上是关于动画自定义视图在屏幕的一半,其中包含图像 - 突然的动画的主要内容,如果未能解决你的问题,请参考以下文章

动画视图仅缩放屏幕宽度的一半

创建自定义视图控制器动画

用动画同时显示 2 个视图控制器

来自 UITableView 的动画 UIView

如何使带有自定义背景图像的按钮在Android中显示点击动画

在自定义 UIView 上为 UIButton 设置动画