【问题标题】:How do implement UIScrollView and UIPageControl Programmatically in Swift4?如何在 Swift4 中以编程方式实现 UIScrollView 和 UIPageControl?
【发布时间】:2020-08-02 01:48:43
【问题描述】:

最近想实现图片和文字幻灯片的UI,个人原因:App页面是通过程序代码实现的。我花了一些时间研究 UIScrollView 和 UIPageControl 的用法,发现这个链接(How to create a Scroll View with a page control using swift?)信息量很大,但是代码在我的环境中不起作用,UIScrollView 的 SubView 没有正确显示,并且有一个滑动切换页面的问题。我花了很多时间寻找问题的答案,但没有找到任何有效信息。

【问题讨论】:

    标签: ios uiscrollview swift4 uipagecontrol


    【解决方案1】:

    更新我的解决方案:

    经过一些练习,问题解决了,我会贴出笔记和解决方案。

    记住:

    1、你的UIScrollView必须有left(或leading)/top/width/height值。

    2、你的 UIScrollView 的内容元素需要定义 contentSize 的边界——但它们是通过底部和右侧(尾随)约束来实现的。

    3、每个 UIScrollView 的中间 SubView 都需要一些左(或前导)和右(尾)约束。详情见代码示例。

    class NTDummyVC: UIViewController, UIScrollViewDelegate {
    
        let SCROLLVIEW_HIGHT:CGFloat = 500
    
        let PAGECONTROL_WIDTH:CGFloat = 200
        let PAGECONTROL_HIGHT:CGFloat = 50
    
        var scrollView = UIScrollView()
        var pageControl = UIPageControl()
    
        var contentViewArray: NSMutableArray = NSMutableArray()
    
        var imageArray: NSArray = ["ImageName one",
                                   "ImageName two",
                                   "ImageName three"]
    
        var titleArray: NSArray = [NSLocalizedString("Title one", comment: ""),
                                   NSLocalizedString("Title two", comment: ""),
                                   NSLocalizedString("Title three", comment: "")]
    
        var subTitleArray: NSArray = [NSLocalizedString("SubTitle one", comment: ""),
                                      NSLocalizedString("SubTitle two", comment: ""),
                                      NSLocalizedString("SubTitle three", comment: "")]
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.backgroundColor = .white
            initScrollView()
            initPageControl()
            loadScrollView()
            //After loading all SubViews, update the contentSize of UIScrollView according to the number of Subviews.
            let scrollViewWidth = scrollView.frame.size.width * CGFloat(getPageCount())
            self.scrollView.contentSize = CGSize(width: scrollViewWidth, height: scrollView.frame.size.height)
        }
    
        func getTopbarHeight() -> CGFloat {
            let statusBarHeight = UIApplication.shared.statusBarFrame.height
            let navigationBarHeight = navigationController?.navigationBar.frame.height ?? 0.0
            return statusBarHeight + navigationBarHeight
        }
    
        func getPageCount() -> Int {
            var pageCount = 0
            pageCount = imageArray.count
            if titleArray.count < pageCount {
            pageCount = titleArray.count
            }
            if subTitleArray.count < pageCount {
                pageCount = subTitleArray.count
            }
            return pageCount
        }
    
        func initScrollView() {
            self.scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: SCROLLVIEW_HIGHT))
            self.scrollView.delegate = self
            self.scrollView.bounces = false
            self.scrollView.isPagingEnabled = true
            self.scrollView.showsVerticalScrollIndicator = false
            self.scrollView.showsHorizontalScrollIndicator = false
            self.view.addSubview(self.scrollView)
            //Constraints for ScrollView, by snapkit tool.
            self.scrollView.snp.makeConstraints { (make) in
                make.width.equalToSuperview()
                make.height.equalTo(SCROLLVIEW_HIGHT)
                make.top.equalToSuperview().offset(getTopbarHeight())
                make.leading.equalToSuperview()
            }
        }
    
        func initPageControl() {
            self.pageControl.numberOfPages = getPageCount()
            self.pageControl.currentPage = 0
            self.pageControl.tintColor = UIColor.gray
            self.pageControl.pageIndicatorTintColor = UIColor.gray
            self.pageControl.currentPageIndicatorTintColor = UIColor.green
            self.view.addSubview(pageControl)
            //Constraint displayed in the center, by snapkit tool.
            self.pageControl.snp.makeConstraints { (make) in
                make.width.equalTo(PAGECONTROL_WIDTH)
                make.height.equalTo(PAGECONTROL_HIGHT)
                make.top.equalTo(self.scrollView.snp.bottom).offset(10)
                make.leading.equalToSuperview()
                make.trailing.equalToSuperview()
                make.centerX.equalToSuperview()
            }
            pageControl.addTarget(self, action: #selector(self.changePage(sender:)), for: UIControlEvents.valueChanged)
        }
    
        func loadScrollView() {
            let pageCount = getPageCount()
            for index in 0...(pageCount - 1) {
                var frame = CGRect.zero
                frame.origin.x = self.scrollView.frame.size.width * CGFloat(index)
                frame.origin.y = 0
                frame.size = self.scrollView.frame.size
    
                let contentView = UIView(frame: frame)
                contentView.backgroundColor = .white
                self.scrollView.addSubview(contentView)
                //Constraints for SubView, by snapkit tool.
                //Do’t add extra constraints such as top, bottom, width, height, etc., which will cause abnormal display.
                contentView.snp.makeConstraints { (make) in
                    make.width.equalTo(UIUtils.screenWidth())
                    make.height.equalTo(self.scrollView.snp.height)
                    if index >= 1 {
                        let view:UIView = contentViewArray.object(at: index - 1) as! UIView
                        make.leading.equalTo(view.snp.trailing)
                    } else {
                        make.leading.equalTo(0)
                    }
                    if index == (pageCount - 1) {
                        make.trailing.equalTo(0)
                    }
                }
    
                let imageView = UIImageView(image: UIImage(named: imageArray[index] as! String))
                imageView.translatesAutoresizingMaskIntoConstraints = false
                imageView.contentMode = UIViewContentMode.scaleAspectFit
                contentView.addSubview(imageView)
                imageView.snp.makeConstraints { (make) in
                    make.centerX.equalToSuperview()
                }
    
                let titleLabel = UILabel()
                titleLabel.font = UIFont.boldSystemFont(ofSize: 18)
                titleLabel.text = titleArray[index] as? String
                titleLabel.textColor = .black
                titleLabel.numberOfLines = 0
                titleLabel.lineBreakMode = .byWordWrapping
                titleLabel.translatesAutoresizingMaskIntoConstraints = false
                contentView.addSubview(titleLabel)
                titleLabel.snp.makeConstraints { (make) in
                    make.top.equalTo(imageView.snp.bottom).offset(30)
                    make.leading.equalToSuperview().offset(30)
                    make.trailing.equalToSuperview().offset(-30)
                }
    
                let subTitleLabel = UILabel()
                subTitleLabel.font = UIFont.boldSystemFont(ofSize: 12)
                subTitleLabel.text = subTitleArray[index] as? String
                subTitleLabel.textColor = UIUtils.color(2)
                subTitleLabel.numberOfLines = 0
                subTitleLabel.lineBreakMode = .byWordWrapping
                subTitleLabel.translatesAutoresizingMaskIntoConstraints = false
                contentView.addSubview(subTitleLabel)
                subTitleLabel.snp.makeConstraints { (make) in
                    make.top.equalTo(titleLabel.snp.bottom).offset(5)
                    make.leading.equalToSuperview().offset(30)
                    make.trailing.equalToSuperview().offset(-30)
                }
    
                if (contentViewArray.contains(contentView)) {
                    contentViewArray.replaceObject(at: contentViewArray.index(of: contentView), with: contentView)
                } else {
                    contentViewArray.insert(contentView, at: index)
                }
            }
        }
    
        // MARK : To Change while clicking on page control
        @objc func changePage(sender: AnyObject) -> () {
            let x = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
            scrollView.setContentOffset(CGPoint(x:x, y:0), animated: true)
        }
    
        // MARK : When UIScrollView slides over, update PageControl
        func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
            pageControl.currentPage = Int(pageNumber)
        }
    }
    

    希望对遇到同样问题的人有所帮助。

    【讨论】:

      猜你喜欢
      • 2012-04-29
      • 2012-02-13
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 2011-03-01
      • 1970-01-01
      • 2015-08-28
      相关资源
      最近更新 更多