【问题标题】:In Swift, how would you write the scrollViewWillEndDragging withVelocity targetContentOffset method?在 Swift 中,你将如何使用 Velocity targetContentOffset 编写 scrollViewWillEndDragging 方法?
【发布时间】:2015-02-17 06:56:15
【问题描述】:

如何用 Swift 编写这个?

更新:发布了我尝试转换的方法,最初发布了一个不同的方法,这不是我想要隐藏的方法

这适用于 Objective C,但不适用于 Swift。当我尝试将ceilffloorfCGFloat 一起使用时出现转换错误。

    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{

    float pageWidth = 200 + 30; // width + space

    float currentOffset = scrollView.contentOffset.x;
    float targetOffset = targetContentOffset->x;
    float newTargetOffset = 0;

    if (targetOffset > currentOffset)
        newTargetOffset = ceilf(currentOffset / pageWidth) * pageWidth;
    else
        newTargetOffset = floorf(currentOffset / pageWidth) * pageWidth;

    if (newTargetOffset < 0)
        newTargetOffset = 0;
    else if (newTargetOffset > scrollView.contentSize.width)
        newTargetOffset = scrollView.contentSize.width;

    targetContentOffset->x = currentOffset;
    [scrollView setContentOffset:CGPointMake(newTargetOffset, 0) animated:YES];


}

【问题讨论】:

    标签: objective-c xcode swift uicollectionview scrollview


    【解决方案1】:

    也许晚一点,但如果处理 iOS11 + Swift4,恕我直言,所提出的解决方案都不是可行的解决方案。

    下面有一个更适合这个问题的答案,完全使用 Swift 4.1

    override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    
        let pageWidht:CGFloat = 200.0 + 30.0
        let currentOffset = scrollView.contentOffset.x
        let targetOffset = CGFloat(targetContentOffset.pointee.x)
        var newTargetOffset:CGFloat = 0.0
    
        if targetOffset > currentOffset {
            newTargetOffset = CGFloat(ceilf(Float((currentOffset / pageWidht) * pageWidht)))
        }
        else {
            newTargetOffset = CGFloat(floorf(Float((currentOffset / pageWidht) * pageWidht)))
        }
    
        if newTargetOffset < 0.0 {
            newTargetOffset = 0.0
        }
        else if newTargetOffset > scrollView.contentSize.width {
            newTargetOffset = scrollView.contentSize.width
        }
        targetContentOffset.pointee = CGPoint(x: newTargetOffset, y: 0.0)
    }
    

    【讨论】:

    • 感谢您的回答!我试图在滚动到新的 targetContentOffset 时提高速度(例如更快地滑出),有什么想法可以实现这种效果吗?
    • 对于我来说,指出“pointee”而不是“memory”。
    【解决方案2】:

    来自 Christian 的回答:我能够用 Swift 重写它。我将所有内容设置为Float 进行数学运算,然后转换为CGFloat,正如Christian 提到的那样。他的回答在技术上是正确的,但向新的 iOS 开发人员展示这个是如何用 Swift 编写的正是我想要的。

    func scrollViewWillEndDragging(scrollView: UIScrollView!, withVelocity velocity: CGPoint, targetContentOffset: UnsafePointer<CGPoint>) {
    
         var pageWidth = Float(200 + 30)
         var currentOffset = Float(scrollView.contentOffset.x)
         var targetOffset = Float(targetContentOffset.memory.x)
         var newTargetOffset = Float(0)
         var scrollViewWidth = Float(scrollView.contentSize.width)
    
         if targetOffset > currentOffset {
             newTargetOffset = ceilf(currentOffset / pageWidth) * pageWidth
         } else {
             newTargetOffset = floorf(currentOffset / pageWidth) * pageWidth
         }
    
         if newTargetOffset < 0 {
             newTargetOffset = 0
         } else if newTargetOffset > currentOffset {
             newTargetOffset = currentOffset
         }
    
         Float(targetContentOffset.memory.x) == currentOffset
    
         scrollView.setContentOffset(CGPointMake(CGFloat(newTargetOffset), 0), animated: true)
     }
    

    【讨论】:

      【解决方案3】:

      您可以使用ceilfloor。 Apple 现在允许 CGFloat 作为此类常用函数的参数。例如:

      func ceil(x: CGFloat) -> CGFloat
      

      所以在你的例子中:

      ceil(currentOffset/pageWidth)
      

      【讨论】:

      • 对不起,我复制错了方法,你可以看看(这里没有X)
      • 是的,其中不必有 x。你可以这样使用它:ceil(currentOffset/pageWidth)
      • 这样可以工作,但是当我尝试使用 targetoffset 分配当前偏移量时,会引发有关 init 的错误请参见此处: d.pr/i/18fCP
      【解决方案4】:

      好吧,这对我不起作用,我有一个折中的方法,使用scrollViewDidEndDecelerating

          var targetOffSet:CGPoint?
          func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
              var offsetX:CGFloat = targetContentOffset.memory.x
              offsetX -= someValue
              self.targetOffSet = CGPoint(x: offsetX, y: 0)
      }
      func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
          if self.targetOffSet != nil {
              scrollView.setContentOffset(self.targetOffSet!, animated: true)
              self.targetOffSet = nil
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-09
        • 1970-01-01
        • 2015-08-21
        • 2012-08-10
        • 1970-01-01
        • 2015-10-31
        • 2013-09-24
        • 1970-01-01
        相关资源
        最近更新 更多