iOS 閱讀器功能小記——自動閱讀

一言不合先上效果:

自動閱讀GIF.gif

效果分析:

穿透效果:上層view局部變?yōu)橥该?,顯示下層view。并非發(fā)生大小或位置上的改變。

實現(xiàn)思路:

直接上代碼:我是在superController(閱讀界面控制器)上添加一個子控制器視圖childController,以下代碼為childController中代碼。

@property (nonatomic, strong) CADisplayLink *link;//幀定時器
@property (nonatomic, strong) CAShapeLayer  *shapeLayer;
@property (nonatomic, strong) UIImageView  *backImage;
@property (nonatomic, strong) UIImageView  *shadowImage;

@property (nonatomic, assign) CGFloat topY;
@property (nonatomic, assign) CGFloat speed;

@property (nonatomic, assign) BOOL isPaused;
- (void)viewDidLoad {
    [super viewDidLoad];
    
    _backImage = [[UIImageView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:_backImage];
    //創(chuàng)建mask需要的形狀
    _shapeLayer = [CAShapeLayer layer];
    _backImage.layer.mask = _shapeLayer;
    //陰影效果需要的圖片
    _shadowImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 5)];
    _shadowImage.image = [UIImage imageNamed:[self.dk_manager.themeVersion isEqualToString:DKThemeVersionNight] ? @"shadow_line_night":@"shadow_line_dawn"];
    [self.view addSubview:_shadowImage];
    //添加點擊手勢,暫停動畫
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap)];
    [self.view addGestureRecognizer:tap];
}

- (void)updateWithView:(UIImage *)image {
    _shapeLayer.path = [UIBezierPath bezierPathWithRect:self.view.frame].CGPath;
    self.backImage.image = image;
}

這里說明一下,backImage顯示的是superController的view,通過截屏的方式生成image。下面是截屏的代碼。

- (UIImage *)captureView:(UIView *)view {
    CGRect rect = view.bounds;
    UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0f);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [view.layer renderInContext:context];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}
開始做動畫:

需要注意的是mask只關注具體的形狀路徑,和本身的顏色無關,所以掃描的陰影樣式我使用圖片來實現(xiàn)。

- (void)startAuto {
    if (_link == nil) {
        // 啟動定時調用
        _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(getCurrent:)];
        [_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    }
}

-(void)getCurrent:(CADisplayLink *)displayLink{
    self.isRunning = YES;
    if(_topY >= self.view.frame.size.height) {
        _topY = 0;
        self.shadowImage.center = CGPointMake(self.view.center.x, self.shadowImage.bounds.size.height/2);
        
        [_link invalidate];
        _link = nil;
        
        [_delegate finishReadPage:self];
        return;
    }
    _topY += _speed;
    [self setCurrentShadowLayer];
    [self setCurrentMaskLayer];
}

- (void)setCurrentMaskLayer {
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, nil, 0, _topY);
    CGPathAddLineToPoint(path, nil, self.view.frame.size.width, _topY);
    CGPathAddLineToPoint(path, nil, self.view.frame.size.width, self.view.frame.size.height);
    CGPathAddLineToPoint(path, nil, 0, self.view.frame.size.height);
    CGPathCloseSubpath(path);
    
    _shapeLayer.path = path;
    CGPathRelease(path);
}

- (void)setCurrentShadowLayer {
    [UIView animateWithDuration:0.1 animations:^{
        CGPoint pos = self.shadowImage.center;
        pos.y += _speed;
        self.shadowImage.center = pos;
    }];
}
控制暫停
- (void)singleTap {
    _isPaused ^= 1;
    [_link setPaused:_isPaused];
}

小結:

我是通過水波動畫的實現(xiàn)想到這樣實現(xiàn)的,通過CADisplayLink修改shapeLayer的path從而實現(xiàn)view的局部透明效果。可能我的方案不是最佳方案,如果大家有更好的方案可以留言給我,一起學習,謝謝。

補充:

看到評論區(qū)很多朋友問我有沒有demo,所以我做了一個簡單的demo放在GitHub上。希望用到覺得可以的朋友給我點個star或喜歡。謝謝大家。
下載地址:https://github.com/rabbitmouse/ZQAutoReadBookDemo

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 15,208評論 4 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,979評論 25 709
  • 很遺憾覺得學習了這么多年寫作一直是我的弱項,我會悄悄的回避,但是總覺得回避是不對的,希望能慢慢培養(yǎng)寫作的能力,不再害怕。
    亨利來了閱讀 375評論 1 1
  • 數(shù)據(jù)庫鍵空間 Redis 是一個鍵值對(key-value pair)數(shù)據(jù)庫服務器, 服務器中的每個數(shù)據(jù)庫都由一個...
    顏灝_2181閱讀 812評論 0 1
  • 我有一個夢想。 大家都知道的。 你有什么夢想? 是….. 是…… 是…… 是…… 是……
    心之物語閱讀 223評論 0 0

友情鏈接更多精彩內容