使用 ViewCode 点击按钮 Swift 时滚动 ScrollView

Posted

技术标签:

【中文标题】使用 ViewCode 点击按钮 Swift 时滚动 ScrollView【英文标题】:Scroll the ScrollView when tap a button Swift with ViewCode 【发布时间】:2021-12-26 17:01:46 【问题描述】:

我正在使用 ViewCode 在 Swift 中创建一个 ViewPager。 我需要创建以下操作:点击 Next 按钮(方法:actionNextPressed()),然后将滚动视图滚动到下一页(就像向右或向左滚动的 TapGesture)。 这是我的 Swift 代码,到目前为止我尝试过的代码,以及来自 viewpager 的打印屏幕(目前)

PagerViewController.swift

import UIKit
import SnapKit

open class PagerViewController: UIViewController, UIPageViewControllerDelegate 
    private lazy var dimmedView: UIView = 
        let view = UIView()
        view.backgroundColor = .black
        view.alpha = maxDimmedAlpha
        return view
    ()
    
    private lazy var containerView: UIView = 
        let view = UIView()
        view.backgroundColor = UIColor(white: 1, alpha: 0)
        return view
    ()
    
    lazy var scrollView: UIScrollView = 
        let scrollView = UIScrollView()
        scrollView.showsHorizontalScrollIndicator = false
        scrollView.isPagingEnabled = true
        scrollView.contentSize = CGSize(width: view.frame.width * CGFloat(pages.count), height: containerView.frame.height)
        
        for i in 0..<pages.count 
            var page = pages[i]
            let dialog = PageViewController(
                icon: page.icon,
                titleText: page.title,
                descriptionText: page.description,
                titleActionButton: page.titleButton,
                actionButton: page.actionButton
            )!
            scrollView.addSubview(dialog.view)
            scrollView.subviews[i].frame = CGRect(
                x: view.frame.width * CGFloat(i),
                y: 0,
                width: containerView.frame.width,
                height: containerView.frame.height
            )
        
        
        scrollView.delegate = self
        return scrollView
    ()
    
    lazy var pageControl: UIPageControl = 
        let pageControl = UIPageControl()
        pageControl.currentPage = 0
        pageControl.numberOfPages = pages.count
        pageControl.addTarget(self, action: #selector(pageControlTapHandler(sender:)), for: .allEvents)
        pageControl.isUserInteractionEnabled = false
        pageControl.pageIndicatorTintColor = .systemGray
        pageControl.currentPageIndicatorTintColor = .systemBlue
        pageControl.backgroundColor = .white
        return pageControl
    ()
    
    private lazy var directionsButtonsStackView: UIStackView = 
        let view = UIStackView()
        view.axis = .horizontal
        view.distribution = .fillEqually
        view.backgroundColor = .red
        return view
    ()
    
    private lazy var buttonJump = UIButton()
    private lazy var buttonBefore = UIButton()
    private lazy var buttonNext = UIButton()
    private var titleJumpButton: String! = ""
    private let maxDimmedAlpha: CGFloat = 0.6
    open var pages: Array<PageModel>!
    private var currentPage: Int = 0
    
    init?(listPages: Array<PageModel>, titleJumpButton: String) 
        super.init(nibName: nil, bundle: nil)
        self.pages = listPages
        self.titleJumpButton = titleJumpButton
    
    
    required public init?(coder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    
    
    @objc func pageControlTapHandler(sender: UIPageControl) 
        scrollView.scrollTo(horizontalPage: sender.currentPage)
    
    
    open override func viewDidLoad() 
        super.viewDidLoad()
        setupView()
        addViewComponents()
        setupConstraints()
    
    
    private func setupView() 
        self.buttonJump = PageButton(frame: .zero).build(
            context: self,
            title: titleJumpButton!,
            selector: #selector(actionJumpPressed)
        )
        
        self.buttonBefore = PageButton(frame: .zero).build(
            context: self,
            title: "Before",
            selector: #selector(actionBeforePressed)
        )
        self.buttonBefore.backgroundColor = .white
        
        self.buttonNext = PageButton(frame: .zero).build(
            context: self,
            title: "Next",
            selector: #selector(actionNextPressed)
        )
        
        self.buttonJump.setTitle(titleJumpButton, for: .normal)
    
    
    private func addViewComponents() 
        view.addSubview(dimmedView)
        
        containerView.addSubview(scrollView)
        
        containerView.addSubview(pageControl)
        
        directionsButtonsStackView.addArrangedSubview(buttonBefore)
        directionsButtonsStackView.addArrangedSubview(buttonNext)
        containerView.addSubview(directionsButtonsStackView)
        
        containerView.addSubview(buttonJump)
        
        view.addSubview(containerView)
    
    
    private func setupConstraints() 
        dimmedView.snp.makeConstraints  make in
            make.top.equalToSuperview()
            make.bottom.equalToSuperview()
            make.leading.equalToSuperview()
            make.trailing.equalToSuperview()
        
        
        containerView.snp.makeConstraints  make in
            make.top.equalToSuperview().offset(100)
            make.bottom.equalToSuperview().inset(100)
            make.leading.equalToSuperview()
            make.trailing.equalToSuperview()
            make.centerX.equalToSuperview()
            make.centerY.equalToSuperview()
            make.margins.equalTo(20)
        
        
        scrollView.snp.makeConstraints  make in
            make.top.equalToSuperview()
            make.bottom.equalTo(pageControl.snp.top)
            make.leading.equalTo(containerView.snp.leading)
            make.trailing.equalTo(containerView.snp.trailing)
        
        
        pageControl.snp.makeConstraints  make in
            make.bottom.equalTo(directionsButtonsStackView.snp.top)
            make.leading.equalTo(containerView.snp.leading).offset(20)
            make.trailing.equalTo(containerView.snp.trailing).inset(20)
            make.height.equalTo(30)
            make.centerX.equalToSuperview()
        
        
        directionsButtonsStackView.snp.makeConstraints  make in
            make.bottom.equalTo(buttonJump.snp.top)
            make.leading.equalTo(containerView.snp.leading).offset(20)
            make.trailing.equalTo(containerView.snp.trailing).inset(20)
            make.height.equalTo(60)
            make.width.greaterThanOrEqualTo(0)
            make.centerX.equalToSuperview()
        
        
        buttonJump.snp.makeConstraints  make in
            make.bottom.equalToSuperview().inset(10)
            make.leading.equalTo(containerView).offset(20)
            make.trailing.equalTo(containerView).inset(20)
            make.centerX.equalToSuperview()
            make.width.greaterThanOrEqualTo(0)
            make.height.equalTo(50)
        
    
    
    @objc private func actionJumpPressed() 
        self.dismiss(animated: true, completion: nil)
    
    
    @objc private func actionBeforePressed() 
        if currentPage == 0 
            return
         else 
            currentPage -= 1
            pageControl.currentPage = currentPage
        
    
    
    @objc private func actionNextPressed() 
        if currentPage == pages.count 
            return
         else 
            currentPage += 1
            pageControl.currentPage = currentPage
        
    


extension PagerViewController: UIScrollViewDelegate 
    public func scrollViewDidScroll(_ scrollView: UIScrollView) 
        let pageIndex = Int(round(scrollView.contentOffset.x / view.frame.width))
        pageControl.currentPage = pageIndex
        currentPage = pageIndex
    


extension UIScrollView 
    func scrollTo(horizontalPage: Int? = 0) 
        var frame: CGRect = self.frame
        frame.origin.x = frame.size.width * CGFloat(horizontalPage ?? 0)
        self.scrollRectToVisible(frame, animated: true)
    

【问题讨论】:

我认为您的代码正在自行取消:在scrollViewDidScroll 内部,您有一个逻辑可能会取消actionNextPressed 内部正在执行的操作。您需要区分是否是用户滑动,然后使用scrollViewDidScroll 内部的逻辑,如果是按钮按下,则仅使用actionNextPressed 内部的逻辑。 【参考方案1】:

我曾经在 collectionView 上遇到过同样的问题。您必须关闭 .isPagingEnabled,将滚动视图滚动到您想要的位置,然后将其重新打开分页。

 func scrollTo(horizontalPage: Int? = 0) 
    scrollView.isPagingEnabled = false
    var frame: CGRect = self.frame
    frame.origin.x = frame.size.width * CGFloat(horizontalPage ?? 0)
    self.scrollRectToVisible(frame, animated: true)
    scrollView.isPagingEnabled = true


【讨论】:

以上是关于使用 ViewCode 点击按钮 Swift 时滚动 ScrollView的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中使用 UIKit 注册多个按钮点击?

检测 Swift 中按钮的点击

如何使用 swift 中的按钮点击动态更改 textview 中的字体?

Swift - 点击按钮时如何测试标签是不是已更新

Swift 防止按钮重复点击

如何在标签栏按钮点击上创建幻灯片菜单(swift)