• 无限轮播器的bug修复


    前言:上一回实现了轮播器的自动滚动,但是有两个需要处理的bug.

          1.增加需求:当用手拖拽控制轮播器的时候,停止自动滚动.

      2.当同一个页面中有tableView,textView或scrollview时,拖拽这些控件时:轮播器会停止自动轮播,卡住;当松开这些控件时:轮播器先快速轮播,把卡住的时间补回来,再恢复正常.

      原因:界面的控件都是主线程创建的,和用户的操作也都是在主线程中处理的. 当用户拖拽另外的控件时,主线程就忙着处理这些拖拽行为,就不能同时处理轮播器的滚动事件了.

    解决问题1:

      1>.当多出用到同样的代码时,提取成一个方法:本demo中有两处: 添加定时器,移除定时器 

    // 添加定时器
    - (void)addTimer
    {
        self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
    
        // 解决拖动其他控件的时候,图片轮播器不能响应的问题
        // 获取当前主线程的消息循环,把self.timer加到主运行循环中.NSRunLoopCommonModes可以同时处理多个事件.
        [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    }
    
    // 移除定时器
    - (void)removeTimer
    {
        [self.timer invalidate];
        // 所以清空self.timer
        self.timer = nil;
    }

      2>使用代理方法解决问题1. 当即将拖拽时,移除定时器. 完成拖拽是启动定时器.

    #pragma mark - 代理方法
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        // 1.停止定时器,定时器一旦停止,就不能重用了
        [self removeTimer];
    }
    
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
        // 启动定时器
        [self addTimer];
    }

    解决问题2:

      方法1>多线程处理.这里不行. 在ios中处理UI界面的事件,只能在主线程中执行,不能用其他的线程来处理.如果多个线程来处理UI界面.很可能造成混乱冲突.例如UI显示一份数据.要保证同一时间,只有一个人可以修改这份数据. 如果多线程的话就可以有多个人同一时间进行操作.就会冲突.

      方法2>提高Scrollview拖拽事件的优先级,就是让主线程同时处理这两个事件.

    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];// 获取当前主线程的消息循环,把self.timer加到主运行循环中.NSRunLoopCommonModes可以同时处理多个事件.
    
    
  • 相关阅读:
    windows 临界区 InitializeCriticalSectionAndSpinCount以及InitializeCriticalSection的区别
    SRWLock 轻量级的读写锁
    QT 遍历获取Form上的控件
    mssql 查询作业执行情况,耗时 等
    C++ builder FMX 遍历窗口所有控件 并 动态消失
    delphi fmx 控件从天上掉下来
    Vue2入门必知必会
    人人开源&项目脚手架&微服务整合
    Spring Security应用到源码分析
    K8S系统学习笔记总览
  • 原文地址:https://www.cnblogs.com/jiayongqiang/p/5557056.html
Copyright © 2020-2023  润新知