Как программно реализовать UIScrollView и UIPageControl в Swift4? - PullRequest
0 голосов
/ 19 апреля 2020

В последнее время я хочу реализовать пользовательский интерфейс изображения и текстового слайд-шоу по моим личным причинам: страницы приложения реализованы программным кодом. Я потратил некоторое время на изучение использования UIScrollView и UIPageControl и обнаружил, что эта ссылка ( Как создать представление прокрутки с помощью элемента управления страницы с помощью swift? ) очень информативна, но код в Моей среде не работает, SubView UIScrollView не отображается правильно, и существует проблема с скольжением для переключения страниц. Я провел много времени в поисках ответов на вопросы, и я не нашел никакой достоверной информации.

1 Ответ

0 голосов
/ 19 апреля 2020

обновить мое решение:

После некоторой практики проблема будет решена, я опубликую примечания и решения.

Просто запомните:

1 、 Ваш UIScrollView должен имеют значения влево (или в начале) / top / width / height.

2 elements Элементы содержимого вашего UIScrollView должны определять границы contentSize, но они делают это с нижними и правыми (конечными) ограничениями.

3 、 Для среднего SubView каждого UIScrollView требуются некоторые левые (или ведущие) и правые (конечные) ограничения. Подробности см. В примере кода.

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)
    }
}

Надеюсь помочь людям, столкнувшимся с той же проблемой.

...