【发布时间】: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内部的逻辑。