swift 4中的页面控制是不是可以有一个无限的水平分页uiscrollview?

Posted

技术标签:

【中文标题】swift 4中的页面控制是不是可以有一个无限的水平分页uiscrollview?【英文标题】:Is it possible to have an infinite horizontal paging uiscrollview for page control in swift 4?swift 4中的页面控制是否可以有一个无限的水平分页uiscrollview? 【发布时间】:2018-10-29 17:06:40 【问题描述】:

假设我有一个字符串数组,每次滑动时,我希望屏幕上的文本是数组中的随机字符串,而不会到达终点。我该怎么做?

【问题讨论】:

嗯,其实你可以用UIScrollView创建一个无限滚动。不过需要一些技巧。它就像一个实现自定义 UITableView 但需要将 contentOffset 设置为 contentSize 的中心而不使用动画并模拟 scrollView 的动画。 【参考方案1】:

不,您不能拥有无限滚动视图。 UIScrollView 是一个矩形区域的视图。该矩形区域可以很大,但也有限制。

UIPageViewController 可能会做你想做的事。自从我使用它已经有一段时间了,但是查看文档看起来您可以提供一组视图控制器或提供符合 UIPageViewControllerDataSource 协议的 dataSource。听起来您可以使用 dataSource 来提供包含您的字符串的无限视图控制器集。

【讨论】:

【参考方案2】:

您可以使用UIPageViewController 来完成此操作。

这是一个简单的例子(添加一个UIPageViewController到你的故事板,并将它的类设置为InfinitePageViewController):

//
//  InfinitePageViewController.swift
//  InfinitePages
//
//  Created by Don Mag on 10/30/18.
//

import UIKit

// simple random color extension
extension UIColor 
    static func randomColor(saturation: CGFloat = 1, brightness: CGFloat = 1, alpha: CGFloat = 1) -> UIColor 
        let hue = CGFloat(arc4random_uniform(361)) / 360.0
        return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
    


class SinglePageViewController: UIViewController 

    var theLabel: UILabel = 
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .white
        v.textAlignment = .center
        v.numberOfLines = 0
        return v
    ()

    override func viewDidLoad() 
        super.viewDidLoad()

        view.backgroundColor = UIColor.randomColor()

        view.addSubview(theLabel)
        NSLayoutConstraint.activate([
            theLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 40.0),
            theLabel.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -40.0),
            theLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 40.0),
            theLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -40.0),
            ])

    



class InfinitePageViewController: UIPageViewController, UIPageViewControllerDataSource 

    var stringArray = [
        "1 - Do not consider painful what is good for you.",
        "2 - It is better to look ahead and prepare than to look back and regret.",
        "3 - The easiest thing in the world to be is you. The most difficult thing to be is what other people want you to be. Don't let them put you in that position.",
        "4 - A book is a version of the world. If you do not like it, ignore it; or offer your own version in return.",
        "5 - The scientific name for an animal that doesn't either run from or fight its enemies is lunch.",
        "6 - To love is to receive a glimpse of heaven.",
        "7 - Patriotism is your conviction that this country is superior to all other countries because you were born in it.",
        "8 - There is but one temple in the universe and that is the body of man.",
        "9 - It is easier to get forgiveness than permission.",
        "10 - There is always more misery among the lower classes than there is humanity in the higher.",
        "11 - Success is counted sweetest by those who ne'er succeed.",
        "12 - Indifference and neglect often do much more damage than outright dislike.",
        "13 - For what do we live, but to make sport for our neighbours, and laugh at them in our turn?",
        "14 - Last night somebody broke into my apartment and replaced everything with exact duplicates... When I pointed it out to my roommate, he said, 'Do I know you?'",
        "15 - Do not weep; do not wax indignant. Understand.",
        "16 - Work saves us from three great evils: boredom, vice and need.",
        "17 - You can discover what your enemy fears most by observing the means he uses to frighten you.",
        "18 - Rest satisfied with doing well, and leave others to talk of you as they please.",
        "19 - People want economy and they will pay any price to get it.",
        "20 - On the whole human beings want to be good, but not too good, and not quite all the time.",
    ]

    override func viewDidLoad() 
        super.viewDidLoad()

        self.dataSource = self

        // create the first "page"
        let vc = SinglePageViewController()
        vc.theLabel.text = stringArray[0]

        // set it as the initial page VC
        self.setViewControllers([vc], direction: .forward, animated: false, completion: nil)

    

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? 
        // don't allow scrolling backward
        return nil
    

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? 
        let vc = SinglePageViewController()
        let randomIndex = Int(arc4random_uniform(UInt32(stringArray.count)))
        vc.theLabel.text = stringArray[randomIndex]
        return vc
    


这将无限滚动,从stringArray 中为每个新页面选择一个随机字符串。

因为这只是从数组中获取一个随机字符串,所以您完全有可能多次获得相同的字符串 - 甚至是顺序的。如果您不希望这样,一种方法是打乱一个索引号数组,然后单步执行该数组。当你到达终点时,再次随机播放数字并继续。

【讨论】:

不错。我写了一个快速页面视图控制器演示应用程序,并试图将它从工作中推送到 GitHub,但我们的办公室安全由于某种原因阻止了我。 一个小问题:如果你洗牌你的数组,走到最后,然后再次洗牌,如果一次洗牌的最后一个条目与第一个条目相同,你仍然可以获得重复项新的洗牌。我创建了一个“RandomItems”类,它提供数组中的随机项并避免这种情况。 True...最后改组肯定会导致重复项目...您会想要处理这种情况。当然,OP 要求“从有限数组中无限随机显示字符串” - 因此,仅使用该指令,连续显示 5 次相同的字符串将是 有效 的。几乎可以肯定不是他的想法:) 我在 Github 上的 RandomObjects 项目解决了“结尾重复”的问题:github.com/DuncanMC/RandomObjects

以上是关于swift 4中的页面控制是不是可以有一个无限的水平分页uiscrollview?的主要内容,如果未能解决你的问题,请参考以下文章

365. 水壶问题

如何在 spriteKit swift 4 中制作无限背景

表格视图单元格中的滚动视图将无法正确显示图像,并且在 swift 4 中的分页模式下有一个额外的页面

在 Swift 中的页面视图控制器内的视图控制器之间传递数据

swift中标签的页面控制

Swift - 带有 4 个 UIViewController 的 UIPageViewController