自动滚动时 UIScrollView 触摸不起作用

Posted

技术标签:

【中文标题】自动滚动时 UIScrollView 触摸不起作用【英文标题】:UIScrollView touch doesnt work when Auto Scroll 【发布时间】:2020-03-31 07:46:00 【问题描述】:

我有一个 UIScrollView,里面有几个项目。如果有人按下按钮滚动视图开始以特定速度自动滚动,我的应用程序中有一个功能。但这会导致所有触摸在滚动视图中停止工作。我的目标是每当用户开始手动滚动时,我希望自动滚动自动停止。但是当自动滚动运行时,手动滚动停止工作。

这是我的自动滚动代码

self.scrollTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
    self.scrollTimer!.fire()
    RunLoop.current.add(self.scrollTimer!, forMode: RunLoopMode.commonModes)

var yOffset: CGFloat = 0
    var offsetIncrementer: CGFloat = 5

    @objc func timerAction() 
        yOffset += offsetIncrementer
        if quranContainer.frame.height <= yOffset + self.view.frame.height 
            yOffset = 0
        

        DispatchQueue.main.async 
            UIView.animate(withDuration: 1.0) 
                self.scrollView.contentOffset.y = self.yOffset
            
        
    

我的输出 https://youtu.be/QrYovPMvoBo

【问题讨论】:

【参考方案1】:
 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
         super.touchesBegan(touches, with: event)
         stopPlayerTimer() 
  


  override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
        super.touchesEnded(touches, with: event)
        startPlayerTimer()
   


    func startPlayerTimer()
        if self.scrollTimer == nil 
            Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
            self.scrollTimer?.fire()
        
    

    func stopPlayerTimer()
        self.scrollTimer?.invalidate()
        self.scrollTimer = nil
     


安排,然后开火。

self.scrollTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
self.scrollTimer.fire()

因为滚动禁用了计时器的更新。

你的计时器默认不在RunLoop.Mode.tracking


把定时器加入RunLoop的普通模式,然后就ok了

RunLoop.current.add(timer, forMode: RunLoop.Mode.common)

【讨论】:

RunLoop.current.add(self.scrollTimer!, forMode: RunLoopMode.commonModes) 我在问题中添加了我的新代码。请检查...仍然不起作用 试试这个。我开始明白了 touchesBegan 或 end 没有被调用【参考方案2】:

好的,问题解决了。 UIView 动画正在删除 userInteractions。需要通过 animate 方法在 options 中传递 allowUserInteraction

这就是我解决问题的方法:

UIView.animate(withDuration: 1.0,
                           delay: 0,
                           options: [.allowUserInteraction],
                           animations: 
                            self.scrollView.contentOffset.y = self.yOffset
            )

【讨论】:

以上是关于自动滚动时 UIScrollView 触摸不起作用的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 在触摸动作时自动滚动到顶部

目标 C:检测 UIScrollView 上的触摸事件

UIScrollView 可以滚动,但不能来自用户交互

苹果自己关于如何使用自动布局制作水平滚动 UIScrollView 的说明不起作用?

UITextField 触摸事件在 UIScrollView 中不起作用

触摸状态栏时 UIScrollView 滚动到底部