记录开发一个轮播小组件用到的一个解决较复杂问题的思路

设计稿效果图

记录开发一个轮播小组件用到的一个解决较复杂问题的思路

分析过程

乍一看,这个轮播不想通常的轮播那样,只是有一个位移的移动。
这里我们观察这个动画效果,其实是由两个动画效果组合而成的
动画一:位移动画,即视图从下往上移动的动画
动画二:透明度的变化,从透明度1 变为透明度为0

所以,我们就分开来解决这个问题,可以两个功能,一个动画完成位移变化的功能,一个动画完成透明度变化的功能

主要功能代码

///计时器的响应方法
- (void)fadeTimeHandler
{
    self.isRefresing = NO;
    float w = self.frame.size.width;
    float h = self.frame.size.height;
    
    self.isAnimating = YES;
    [self.reuseCells removeObject:_currentCell];
    [self.reuseCells removeObject:_willShowCell];
    ///动画隐藏当前的cell
    /// 透明度动画
    [UIView animateWithDuration:self.animationDuration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        if (self.isRefresing) {
            self.currentCell.alpha = 1;
        } else {
            self.currentCell.alpha = 0;
        }
    } completion:^(BOOL finished) {
    }];
    /// 位移动画
    [UIView animateWithDuration:self.animationDuration - 0.1 delay:0.1 options:UIViewAnimationOptionCurveLinear animations:^{
        if (self.isRefresing) {
            self.currentCell.frame = CGRectMake(0, 0, w, h);
        } else {
            self.currentCell.frame = CGRectMake(0, - self.fadeTranslationY, w, h);
        }
    } completion:^(BOOL finished) {
    }];
    ///动画展示下一个cell ,
    /*
     这里减0.07是需要在上面文案的动画还没有结束的时候,
     下面文案的动画就要开始了
     */
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((self.animationDuration - 0.07) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self showNext];
    });
}

- (void)showNext
{
    [UIView animateWithDuration:self.animationDuration animations:^{
        if (self.isRefresing) {
            self.willShowCell.alpha = 0;
        } else {
            self.willShowCell.alpha = 1;
        }
    } completion:^(BOOL finished) {
    }] ;
    float w = self.frame.size.width;
    float h = self.frame.size.height;
    
    [UIView animateWithDuration:self.animationDuration - 0.1 delay:0.1 options:UIViewAnimationOptionCurveLinear animations:^{
        if (self.isRefresing) {
            self.willShowCell.frame = CGRectMake(0, self.fadeTranslationY, w, h);
        } else {
            self.willShowCell.frame = CGRectMake(0, 0, w, h);
        }
    } completion:^(BOOL finished) {
        if (self.isRefresing) {
            return;
        }
        self->_currentIndex++;
        int count = (int)[self.dataSource numberOfRowsForRollingNoticeView:self];
        if (self->_currentIndex > count - 1) {
            self->_currentIndex = 0;
        }
        if (self.currentCell && self.willShowCell) {
            [self.reuseCells addObject:self.currentCell];
        }
        self.isAnimating = NO;
        int willShowIndex = self->_currentIndex + 1;
        if (willShowIndex > count - 1) {
            willShowIndex = 0;
        }
        self->_currentCell = self->_willShowCell;
        self->_willShowCell = [self.dataSource rollingNoticeView:self cellAtIndex:willShowIndex];
        self->_willShowCell.frame = CGRectMake(0, self.fadeTranslationY, w, h);
        self->_willShowCell.alpha = 0;
        [self addSubview:self.willShowCell];
    }];
}

反思:

我们解决一个较复杂问题的时候,可以将这个问题分解成若干个独立的小问题,这样我们就可以排除干扰,专心的去解决某个小问题,从而解决大的问题

上一篇:android ijkplayer添加防盗链refer,截图,支持rtsp,修改底层增加截图功能,以及ijk播放的部分问题


下一篇:pip换源和Python虚拟环境配置