【问题标题】:How do I make an infinite paged scroll view with image views?如何使用图像视图制作无限分页滚动视图?
【发布时间】:2015-05-29 10:23:51
【问题描述】:

我有一个分页的 UIScrollView,它每 5 秒自动向左滚动 4 个 UIImage 视图。当滚动视图到达第 4 个图像视图时,它会一直滚动回第一个图像视图并重新开始。

创建无限滚动视图错觉的最佳方法是什么?换句话说,我只是希望它继续向前滚动而不是滚动视图,当它到达第 4 个图像视图时,它会向前滚动并且图像视图 #1 就在那里。

我想过当滚动视图到达第四张图片时重新添加图像视图并增加滚动视图的内容大小,但这不是很聪明...... idk

到目前为止,这是我的代码:

我的声明:

var pageImages = [UIImage]()
var pageViews: [UIImageView?] = []
var scrollTimer = NSTimer()
@IBOutlet weak var carousel: UIScrollView!

在 viewDidLoad() 中:

pageImages = [UIImage(named: "featured_1.png")!,
        UIImage(named: "featured_2.png")!,
        UIImage(named: "featured_3.png")!,
        UIImage(named: "featured_4.png")!]
    for _ in 0..<pageImages.count
       pageViews.append(nil)
}
var pagesScrollViewSize = carousel.frame.size

        carousel.contentSize = CGSize(width: pagesScrollViewSize.width * CGFloat(pageImages.count),
            height: pagesScrollViewSize.height)

loadVisiblePages()

以及定时器每5秒调用一次的函数:

func scrollToImage() {
        let x = carousel.contentOffset.x
        if (x <= (carousel.frame.width * CGFloat(pageImages.count))/2) {
        UIView.animateWithDuration(1, animations: {
            self.carousel.contentOffset = CGPointMake(x+self.carousel.frame.width, 0)
        })
        } else {
        UIView.animateWithDuration(1, animations: {
            self.carousel.contentOffset = CGPointMake(self.pageViews[0]!.frame.origin.x, 0)
        })
        }
    }

最后是完成批量工作的辅助函数:

func loadPage(page: Int) {
        if page < 0 || page >= pageImages.count {
            return
        }

        if let pageView = pageViews[page] {

        } else {
            var frame = carousel.bounds
            frame.origin.x = frame.size.width * CGFloat(page)
            frame.origin.y = 0.0

            let newPageView = UIImageView(image: pageImages[page])
            newPageView.contentMode = UIViewContentMode.ScaleToFill
            newPageView.frame = frame
            carousel.addSubview(newPageView)
            pageViews[page] = newPageView
        }
    }

    func loadVisiblePages() {
        let pageWidth = carousel.frame.size.width
        let page = Int(floor((carousel.contentOffset.x * 2.0 + pageWidth) / (pageWidth * 2.0)))

        let firstPage = page
        let lastPage = page + 3

        for index in firstPage...lastPage {
            loadPage(index)
        }
    }

【问题讨论】:

    标签: ios swift uiscrollview


    【解决方案1】:

    这个想法是:

    当图像在左侧超出框架时,将其移除并重新附加到最右侧图像的右侧。此时您重置内容偏移量

    import UIKit
    
    class ViewController: UIViewController {
    
        var pageViews: [UIImageView] = []
        var scrollTimer = NSTimer()
    
        @IBOutlet weak var carousel: UIScrollView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            pageViews = [
                UIImageView(image:UIImage(named: "featured_1.png")!),
                UIImageView(image:UIImage(named: "featured_2.png")!),
                UIImageView(image:UIImage(named: "featured_3.png")!),
                UIImageView(image:UIImage(named: "featured_4.png")!)
            ]
            var pagesScrollViewSize = carousel.frame.size
            carousel.contentSize = CGSize(width: pagesScrollViewSize.width * CGFloat(pageViews.count),height: pagesScrollViewSize.height)
            println(carousel.contentSize)
    
            scrollTimer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "moveLeft", userInfo: nil, repeats: true)
        }
    
        override func viewDidAppear(animated: Bool) {
            showPage()
        }
    
        func showPage(){
            carousel.setContentOffset(CGPointZero, animated: false)
            for (index, page) in enumerate(pageViews) {
                var frame = page.frame
                frame.origin.x = carousel.frame.size.width * CGFloat(index)
                frame.origin.y = 0.0
                println(frame)
                page.contentMode = UIViewContentMode.ScaleToFill
                page.frame = frame
                carousel.addSubview(page)
            }
    
        }
    
        func moveLeft(){
            UIView.animateWithDuration(
                1.0,
                animations: {
                    let x = self.carousel.contentOffset.x
                    self.carousel.contentOffset = CGPointMake(x + self.carousel.frame.width, 0)
                    println(self.carousel.contentOffset)
                }, completion: {complete in
                    self.moveLeftEnd()
                }
            );
        }
    
        func moveLeftEnd(){
            let first = pageViews.removeAtIndex(0)
            pageViews.append(first)
            showPage()
        }
    }
    

    【讨论】:

    • 这个,我建议你看这个WWDC video,它演示了如何实现这个效果。
    • 这实际上不起作用,但感谢您的帮助和您的时间!第一个图像视图滚动到下一个图像,然后滚动视图类型闪烁,我们回到第一个图像视图。这是第一个和第二个图像视图之间的一种不稳定循环
    • 我很抱歉,其中一个功能有错误,我没有看到它,因为我所有的图像看起来都一样。现在可以 100% 工作,检查我所做的编辑,它取代了 moveLeftEnd() 函数。
    • 效果很好!谢谢!您实际上所做的是删除离开屏幕的图像并将其添加到数组的末尾,对吗?这会对CPU产生重大影响吗?我注意到的另一个问题是手动滚动图像会导致图像视图偏移,并且动画的其余部分会混乱。我的旧实现没有发生这种情况。有没有办法解决这个问题?另外我想一个警告是无法向后滚动,嗯
    • 终于想出了一个比上面那个简单得多的方法。一会儿回答问题
    猜你喜欢
    • 2012-02-26
    • 2020-06-22
    • 2013-10-28
    • 2023-03-12
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多