我正在尝试在我的UIScrollView中实现“循环”滚动,但尝试未果。
我想要做的是: 如果UIScrollView到达末尾,它应该移动到开头 如果UIScrollView在开头并且向后移动,它应该移动到末尾
在我的情况下,附加滚动视图不是好的方法(其他方法应该获取“页面ID”)
你有什么想法吗?
我正在尝试在我的UIScrollView中实现“循环”滚动,但尝试未果。
我想要做的是: 如果UIScrollView到达末尾,它应该移动到开头 如果UIScrollView在开头并且向后移动,它应该移动到末尾
在我的情况下,附加滚动视图不是好的方法(其他方法应该获取“页面ID”)
你有什么想法吗?
我已经实现了这个方法,但是它要求分页启用。假设你有五个元素 A,B,C,D和E
。当你设置你的视图时,你把最后一个元素添加到开头,把第一个元素添加到结尾,并调整内容偏移量以查看第一个元素,像这样 E,[A],B,C,D,E,A
。在UIScrollViewDelegate中,检查用户是否到达任何一端,并将偏移值无动画地移动到另一端。
想象一下[ ]表示正在显示的视图:
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
中。
尽情享受吧!
UICollectionView
现在是推荐的方法,并且可以用来获得完全相同的行为。 这篇教程详细描述了如何实现这一点。
scrollViewDidEndDecelerating
代理方法中进行切换。我已经添加了一个完整的示例,你可以使用它或者查看它是如何实现的。 - redent84苹果公司有一个Street Scroller演示,看起来正是你所需要的。
此外,还有一个视频来自2011 WWDC展示他们的演示。 ;) 他们在视频中首先介绍了无限滚动。
UIPageControl
并简单修改代码,在你超出实际索引区域时使用余数数学。 - mbm29414尝试使用以下代码...
示例代码...
- (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];
}
}
希望这能对你有所帮助...
参考 @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
}
}