西贝了爷  

前言:上一回实现了轮播器的自动滚动,但是有两个需要处理的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可以同时处理多个事件.

posted on 2016-06-03 17:33  西贝了爷  阅读(401)  评论(0编辑  收藏  举报