CollectionView + 页面控件
CollectionView + Page control
我有 collectionView,其中每个单元格都是一个页面(单元格在纵向模式下占据整个屏幕,在横向模式下占据 2 个单元格)。我正在尝试添加当前页面 number/the 总页数(即 1/30)我到目前为止得到的 1/0 --> 一个是当前页码,0 是总页数。
有两个问题:
- 仅当我开始滚动时才显示总页数
- 当我滚动时,当前页码没有改变。
我使用的代码:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if pageControl.currentPage < pages.count {
pageControl.currentPage += 1
numberOfPagesLabel.text = "\(pageControl.currentPage + 1)/\(pages.count)"
} else if pageControl.currentPage != 0 {
pageControl.currentPage -= 1
numberOfPagesLabel.text = "\(pageControl.currentPage - 1)/\(pages.count)"
}
}
class DetailsViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIScrollViewDelegate {
private var collectionView: UICollectionView!
let pageControl = UIPageControl (frame: CGRect(x: 20, y: 120, width: 44, height: 44))
let numberOfPagesLabel = UILabel (frame: CGRect(x: 20, y: 0, width: 44, height: 44))
private var pages = [Pages]() {
didSet {
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
numberOfPagesLabel.layer.cornerRadius = 15.0
numberOfPagesLabel.clipsToBounds = true
numberOfPagesLabel.center.x = self.view.center.x
numberOfPagesLabel.center.y = self.view.center.y+350
self.view.addSubview(collectionView)
self.view.addSubview(pageControl)
self.view.addSubview(numberOfPagesLabel)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
collectionViewLayout()
collectionView.delegate = self
collectionView.dataSource = self
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if pageControl.currentPage < pages.count {
pageControl.currentPage += 1
numberOfPagesLabel.text = "\(pageControl.currentPage + 1)/\(pages.count)"
} else if pageControl.currentPage != 0 {
pageControl.currentPage -= 1
numberOfPagesLabel.text = "\(pageControl.currentPage - 1)/\(pages.count)"
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return pages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "colCell7", for: indexPath) as! colCell7
let book = pages[indexPath.row]
cell.setupCell(for: book)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if UIWindow.isLandscape {
return CGSize(width: (collectionView.frame.size.width)/2, height: (collectionView.frame.size.height))
}
else { return CGSize(width: (collectionView.frame.size.width), height: (collectionView.frame.size.height))
}
}
func collectionViewLayout() {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: layout)
collectionView.backgroundColor = .white
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
collectionView.isPagingEnabled = true
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.register(colCell7.self, forCellWithReuseIdentifier: "colCell7")
collectionView.isScrollEnabled = true
collectionView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
layout.itemSize = CGSize(width: view.frame.width, height: view.frame.height)
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.itemSize = CGSize(width: view.frame.width/2, height:view.frame.height )
}
}
尝试使用此代码获取 CollectionView 中的当前页面:
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// for horizontal scroll
let currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
// for vertical scroll
// let currentPage = Int(scrollView.contentOffset.y) / Int(scrollView.frame.height)
pageControl.currentPage = currentPage
numberOfPagesLabel.text = "\(self.pages.count)/\(self.pageControl.currentPage - 1)"
}
最好在滚动结束减速时,在 scrollViewDidEndDecelerating 函数中添加用于检测当前页面的计算器代码。
完整代码:
public struct Pages {
public var title: String
}
class DetailsViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
private var collectionView: UICollectionView!
let pageControl = UIPageControl (frame: CGRect(x: 20, y: 120, width: 44, height: 44))
let numberOfPagesLabel = UILabel (frame: CGRect(x: 20, y: 0, width: 44, height: 44))
private var pages = [Pages]() {
didSet {
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.numberOfPagesLabel.textColor = .red
self.numberOfPagesLabel.backgroundColor = .blue
collectionViewLayout()
collectionView.delegate = self
collectionView.dataSource = self
self.view.addSubview(collectionView)
self.view.addSubview(pageControl)
self.view.addSubview(numberOfPagesLabel)
numberOfPagesLabel.translatesAutoresizingMaskIntoConstraints = false
numberOfPagesLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 20).isActive = true
numberOfPagesLabel.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 20).isActive = true
self.collectionView.register(UINib.init(nibName: "colCell7", bundle: nil), forCellWithReuseIdentifier: "colCell7")
numberOfPagesLabel.layer.cornerRadius = 15.0
numberOfPagesLabel.clipsToBounds = true
numberOfPagesLabel.center.x = self.view.center.x
numberOfPagesLabel.center.y = self.view.center.y+350
collectionView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
collectionView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
collectionView.heightAnchor.constraint(equalTo: self.view.heightAnchor).isActive = true
collectionView.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true
pages = [.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1")]
pageControl.numberOfPages = pages.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return pages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "colCell7", for: indexPath) as! colCell7
let book = pages[indexPath.row]
cell.setupCell(pages: book)
return cell
}
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// for horizontal scroll
let currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
// for vertical scroll
// let currentPage = Int(scrollView.contentOffset.y) / Int(scrollView.frame.height)
pageControl.currentPage = currentPage
numberOfPagesLabel.text = "\(self.pages.count)/\(currentPage)"
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (collectionView.frame.size.width), height: (collectionView.frame.size.height))
}
func collectionViewLayout() {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: layout)
collectionView.backgroundColor = .white
collectionView.delegate = self
collectionView.dataSource = self
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
collectionView.isPagingEnabled = true
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.isScrollEnabled = true
layout.itemSize = CGSize(width: view.frame.width, height: view.frame.height)
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.itemSize = CGSize(width: view.frame.width/2, height:view.frame.height )
}
}
输出:
我明白了。下面的代码适用于横向排列(2 个单元格)和纵向排列(1 个单元格)我仍然有一个问题,直到滚动开始才出现计数。
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if UIWindow.isLandscape {
let x = scrollView.contentOffset.x
let w = scrollView.bounds.size.width/2
let currentPage = Int(ceil(x/w))
numberOfPagesLabel.text = "\(self.pages.count)/\(currentPage + 2)"
pageControl.currentPage = Int(currentPage) }
else
{
let x = scrollView.contentOffset.x
let w = scrollView.bounds.size.width
let currentPage = Int(ceil(x/w))
numberOfPagesLabel.text = "\(self.pages.count)/\(currentPage + 1)"
pageControl.currentPage = Int(currentPage)
}
extension UIWindow {
static var isLandscape: Bool {
if #available(iOS 13.0, *) {
return UIApplication.shared.windows
.first?
.windowScene?
.interfaceOrientation
.isLandscape ?? false
} else {
return UIApplication.shared.statusBarOrientation.isLandscape
}
}
}
我有 collectionView,其中每个单元格都是一个页面(单元格在纵向模式下占据整个屏幕,在横向模式下占据 2 个单元格)。我正在尝试添加当前页面 number/the 总页数(即 1/30)我到目前为止得到的 1/0 --> 一个是当前页码,0 是总页数。
有两个问题:
- 仅当我开始滚动时才显示总页数
- 当我滚动时,当前页码没有改变。
我使用的代码:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if pageControl.currentPage < pages.count {
pageControl.currentPage += 1
numberOfPagesLabel.text = "\(pageControl.currentPage + 1)/\(pages.count)"
} else if pageControl.currentPage != 0 {
pageControl.currentPage -= 1
numberOfPagesLabel.text = "\(pageControl.currentPage - 1)/\(pages.count)"
}
}
class DetailsViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIScrollViewDelegate {
private var collectionView: UICollectionView!
let pageControl = UIPageControl (frame: CGRect(x: 20, y: 120, width: 44, height: 44))
let numberOfPagesLabel = UILabel (frame: CGRect(x: 20, y: 0, width: 44, height: 44))
private var pages = [Pages]() {
didSet {
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
numberOfPagesLabel.layer.cornerRadius = 15.0
numberOfPagesLabel.clipsToBounds = true
numberOfPagesLabel.center.x = self.view.center.x
numberOfPagesLabel.center.y = self.view.center.y+350
self.view.addSubview(collectionView)
self.view.addSubview(pageControl)
self.view.addSubview(numberOfPagesLabel)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
collectionViewLayout()
collectionView.delegate = self
collectionView.dataSource = self
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if pageControl.currentPage < pages.count {
pageControl.currentPage += 1
numberOfPagesLabel.text = "\(pageControl.currentPage + 1)/\(pages.count)"
} else if pageControl.currentPage != 0 {
pageControl.currentPage -= 1
numberOfPagesLabel.text = "\(pageControl.currentPage - 1)/\(pages.count)"
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return pages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "colCell7", for: indexPath) as! colCell7
let book = pages[indexPath.row]
cell.setupCell(for: book)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if UIWindow.isLandscape {
return CGSize(width: (collectionView.frame.size.width)/2, height: (collectionView.frame.size.height))
}
else { return CGSize(width: (collectionView.frame.size.width), height: (collectionView.frame.size.height))
}
}
func collectionViewLayout() {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: layout)
collectionView.backgroundColor = .white
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
collectionView.isPagingEnabled = true
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.register(colCell7.self, forCellWithReuseIdentifier: "colCell7")
collectionView.isScrollEnabled = true
collectionView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
layout.itemSize = CGSize(width: view.frame.width, height: view.frame.height)
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.itemSize = CGSize(width: view.frame.width/2, height:view.frame.height )
}
}
尝试使用此代码获取 CollectionView 中的当前页面:
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// for horizontal scroll
let currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
// for vertical scroll
// let currentPage = Int(scrollView.contentOffset.y) / Int(scrollView.frame.height)
pageControl.currentPage = currentPage
numberOfPagesLabel.text = "\(self.pages.count)/\(self.pageControl.currentPage - 1)"
}
最好在滚动结束减速时,在 scrollViewDidEndDecelerating 函数中添加用于检测当前页面的计算器代码。
完整代码:
public struct Pages {
public var title: String
}
class DetailsViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
private var collectionView: UICollectionView!
let pageControl = UIPageControl (frame: CGRect(x: 20, y: 120, width: 44, height: 44))
let numberOfPagesLabel = UILabel (frame: CGRect(x: 20, y: 0, width: 44, height: 44))
private var pages = [Pages]() {
didSet {
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.numberOfPagesLabel.textColor = .red
self.numberOfPagesLabel.backgroundColor = .blue
collectionViewLayout()
collectionView.delegate = self
collectionView.dataSource = self
self.view.addSubview(collectionView)
self.view.addSubview(pageControl)
self.view.addSubview(numberOfPagesLabel)
numberOfPagesLabel.translatesAutoresizingMaskIntoConstraints = false
numberOfPagesLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 20).isActive = true
numberOfPagesLabel.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 20).isActive = true
self.collectionView.register(UINib.init(nibName: "colCell7", bundle: nil), forCellWithReuseIdentifier: "colCell7")
numberOfPagesLabel.layer.cornerRadius = 15.0
numberOfPagesLabel.clipsToBounds = true
numberOfPagesLabel.center.x = self.view.center.x
numberOfPagesLabel.center.y = self.view.center.y+350
collectionView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
collectionView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
collectionView.heightAnchor.constraint(equalTo: self.view.heightAnchor).isActive = true
collectionView.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true
pages = [.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1"),
.init(title: "1")]
pageControl.numberOfPages = pages.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return pages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "colCell7", for: indexPath) as! colCell7
let book = pages[indexPath.row]
cell.setupCell(pages: book)
return cell
}
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// for horizontal scroll
let currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
// for vertical scroll
// let currentPage = Int(scrollView.contentOffset.y) / Int(scrollView.frame.height)
pageControl.currentPage = currentPage
numberOfPagesLabel.text = "\(self.pages.count)/\(currentPage)"
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (collectionView.frame.size.width), height: (collectionView.frame.size.height))
}
func collectionViewLayout() {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: layout)
collectionView.backgroundColor = .white
collectionView.delegate = self
collectionView.dataSource = self
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
collectionView.isPagingEnabled = true
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.isScrollEnabled = true
layout.itemSize = CGSize(width: view.frame.width, height: view.frame.height)
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.itemSize = CGSize(width: view.frame.width/2, height:view.frame.height )
}
}
输出:
我明白了。下面的代码适用于横向排列(2 个单元格)和纵向排列(1 个单元格)我仍然有一个问题,直到滚动开始才出现计数。
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if UIWindow.isLandscape {
let x = scrollView.contentOffset.x
let w = scrollView.bounds.size.width/2
let currentPage = Int(ceil(x/w))
numberOfPagesLabel.text = "\(self.pages.count)/\(currentPage + 2)"
pageControl.currentPage = Int(currentPage) }
else
{
let x = scrollView.contentOffset.x
let w = scrollView.bounds.size.width
let currentPage = Int(ceil(x/w))
numberOfPagesLabel.text = "\(self.pages.count)/\(currentPage + 1)"
pageControl.currentPage = Int(currentPage)
}
extension UIWindow {
static var isLandscape: Bool {
if #available(iOS 13.0, *) {
return UIApplication.shared.windows
.first?
.windowScene?
.interfaceOrientation
.isLandscape ?? false
} else {
return UIApplication.shared.statusBarOrientation.isLandscape
}
}
}