【问题标题】:UIScrollView with "Circular" scrolling带有“循环”滚动的 UIScrollView
【发布时间】:2012-05-13 22:53:41
【问题描述】:

我试图在我的 UIScrollView 中进行“循环”滚动,但没有成功。

我想做什么: 如果 uiscrollview 到达结束,它应该移动开始 如果 uiscrollview 在开始并向后移动,它应该移动到结束

在我的情况下附加滚动视图不是好方法(其他方法应该得到“页面ID”)

你有什么想法吗?

【问题讨论】:

  • 使用滚动视图属性我明白你要问什么了。
  • 现在我有搜索,我在我的项目中使用它,我想你想要左侧和右侧一张一张图片,背面也一张图片,它像水平圆圈一样旋转。

标签: iphone ios cocoa-touch uiscrollview uikit


【解决方案1】:

尝试使用以下代码..

示例代码..

- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender 
    {

        if (scrollView.contentOffset.x == 0) {
            // user is scrolling to the left from image 1 to image n(last image).
            // reposition offset to show image 10 that is on the right in the scroll view
            [scrollView scrollRectToVisible:CGRectMake(4000,0,320,480) animated:NO];// you can define your `contensize` for scrollview
        }
        else if (scrollView.contentOffset.x == 4320) {
            // user is scrolling to the right from image n(last image) to image 1.
            // reposition offset to show image 1 that is on the left in the scroll view
            [scrollView scrollRectToVisible:CGRectMake(320,0,320,480) animated:NO];
        }
    }

希望对你有所帮助...

【讨论】:

  • 上面的代码应该可以工作,但我不知道为什么它不工作。比访问此网址后。它还包含示例代码 >>> mobiledevelopertips.com/user-interface/… ...
  • 这段代码具体是如何解决提问者的问题的?
【解决方案2】:

我已经实现了这个方法,但是它需要启用分页。假设您有五个元素A,B,C,D and E。设置视图时,将最后一个元素添加到开头,将第一个元素添加到结尾,并调整内容偏移量以查看第一个元素,例如 E,[A],B,C,D,E,A。在 UIScrollViewDelegate 中,检查用户是否到达任何一端,并将偏移 without 动画移动到另一端。

想象一下 [ ] 表示正在显示的视图:

E,A,B,C,[D],E,A

用户向右滑动

E,A,B,C,D,[E],A

用户向右滑动

E,A,B,C,D,E,[A]

然后,自动设置内容偏移到第二个元素

E,[A],B,C,D,E,A

通过这种方式,用户可以双向滑动创建无限滚动的错觉。

E,A,[B],C,D,E,A


更新

我已经上传了该算法的完整实现。这是一个非常复杂的类,因为它还具有点击选择、无限循环滚动和单元格重用。您可以按原样使用代码,修改它或提取您需要的代码。最有趣的代码在 TCHorizontalSelectorView 类中。

Link to the file

尽情享受吧!


更新 2

UICollectionView 现在是实现此目的的推荐方法,它可用于获得完全相同的行为。 This tutorial详细描述了如何实现。

【讨论】:

  • 我的滚动视图已启用分页
  • 谢谢,这是一个很好的解决方案。
  • 我应该使用哪个事件从最后一个元素转到第二个?
  • @sMember 你在scrollViewDidEndDecelerating 委托方法中切换。我已经添加了一个完整的例子,你可以使用它或检查它是如何完成的。
  • 很好的解决方案解释得很好:) +1
【解决方案3】:

Apple 有一个 Street Scroller 演示,看起来正是你想要的。

还有来自 WWDC 2011 的 video 演示了他们的演示。 ;) 他们首先在视频中介绍了无限滚动。

【讨论】:

  • +1 不错,但它不适用于分页,至少不是开箱即用。我尝试启用分页,但框架似乎比显示器大。可能会进行一些调整。
  • @Kai 这并不是真的用于分页,我不确定 OP 是否真的 想要 分页。我知道它已启用,但无限滚动!= 分页。根据他的问题,这听起来更像是横向卷轴游戏,而不是无限的掩护流。如果它实际上是分页,您可以使用 Apple 的演示来加载 UIPageControl,并在您超出实际索引区域时简单地修改代码以使用余数。
【解决方案4】:

参考@redent84,找到代码逻辑。

覆盖 func viewWillAppear(_ animated: Bool)

{
    super.viewWillAppear(animated)

    scrollView.contentSize = CGSize(width: scrollView.frame.width * CGFloat(imagesArray.count), height: scrollView.frame.height)

    scrollView.isPagingEnabled = true

    //        imagesArray.insert(imagesArray.last as? UIImage, at: 0)
    //        imagesArray.insert(imagesArray.first as? UIImage, at: imagesArray.count - 1)


    var testArr = ["A", "B", "C", "D"]

    let firstItem = testArr.first
    let lastItem = testArr.last

    testArr.insert(lastItem as! String, at: 0)
    testArr.append(firstItem as! String)
    print(testArr)


    for i in 0..<imagesArray.count{
        let imageview = UIImageView()
        imageview.image = imagesArray[i]
        imageview.contentMode = .scaleAspectFit
        imageview.clipsToBounds = true
        let xPosition = self.scrollView.frame.width * CGFloat(i)
        imageview.frame = CGRect(x: xPosition, y: 0, width: self.scrollView.frame.width, height: self.scrollView.frame.height)
        print(imageview)
        scrollView.addSubview(imageview)

        print("Imageview frames of i \(i) is \(imageview.frame)")
    }

    newStartScrolling()
}

func newStartScrolling()
{
    ViewController.i += 1

    let x = CGFloat(ViewController.i) * scrollView.frame.size.width
    scrollView.setContentOffset(CGPoint(x: x, y: 0), animated: true)

    print("X is \(x) and i is \(ViewController.i)")

    if ViewController.i == imagesArray.count - 1 {
        ViewController.i = 0
        let x = CGFloat(ViewController.i) * scrollView.frame.size.width
        //scrollView.setContentOffset(CGPoint(x: x, y: 0), animated: false)
        print("X (rotate) is \(x) and i is \(ViewController.i)")
        scrollView.contentOffset.x = x
        self.newStartScrolling()

    }

}

func backScrolling()  {
    ViewController.i -= 1

    let x = CGFloat(ViewController.i) * scrollView.frame.size.width
    scrollView.setContentOffset(CGPoint(x: x, y: 0), animated: true)
    print("X is \(x) and i is \(ViewController.i)")
    if ViewController.i <= 0 {
        ViewController.i = imagesArray.count - 1
        let x = CGFloat(ViewController.i) * scrollView.frame.size.width
         scrollView.setContentOffset(CGPoint(x: x, y: 0), animated: false)
        print("X (rotate) is \(x) and i is \(ViewController.i)")

        self.backScrolling()
        //scrollView.contentOffset.x = x
        return
    }

}

【讨论】:

    猜你喜欢
    • 2011-10-07
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多