Как добавить PageControl внутри UICollectionView Image Scrolling
Здравствуйте, у меня есть UICollectionView
Горизонтальные коды листинга изображений, которые я хочу добавить PageControl
, когда будут отображаться прокрутки изображений, я добавил селектор pagecontrol и IBOutlet
, но как я могу его интегрировать? между UICollecitonView
.?
Мои коды ниже.
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var View : DesignableView!
@IBOutlet var collectionView: UICollectionView!
@IBOutlet var collectionViewLayout: UICollectionViewFlowLayout!
@IBOutlet open weak var pageControl: UIPageControl? {
didSet {
pageControl?.addTarget(self, action: #selector(ViewController.pageChanged(_:)), for: .valueChanged)
}
}
override func viewDidLoad() {
super.viewDidLoad()
pageControl?.numberOfPages = 11
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 11;
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: ImageCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as! ImageCollectionViewCell
cell.label.text = "Cell \(indexPath.row)"
cell.backgroundImageView.image = UIImage(named: "Parallax \(indexPath.row + 1)")
// Parallax cell setup
cell.parallaxTheImageViewScrollOffset(self.collectionView.contentOffset, scrollDirection: self.collectionViewLayout.scrollDirection)
return cell
}
@IBAction open func pageChanged(_ sender: UIPageControl) {
print(sender.currentPage)
}
// MARK: Delegate
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return collectionView.bounds.size;
}
// MARK: Scrolling
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Parallax visible cells
for cell: ImageCollectionViewCell in collectionView.visibleCells as! [ImageCollectionViewCell] {
cell.parallaxTheImageViewScrollOffset(self.collectionView.contentOffset, scrollDirection: self.collectionViewLayout.scrollDirection)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Ответы
Ответ 1
Здесь у вас есть полный класс с разбивкой по страницам в виде горизонтальной коллекции.
Сейчас он работает над одним из моих приложений и работает правильно. Если вы не можете заставить его работать, не стесняйтесь спрашивать меня, и я помогу вам.
Во-первых, в раскадровке вы должны настроить свой CollectionView с помощью
Макет: поток
Направление прокрутки: Горизонтальное
Прокрутка включена
Пейджинг включен
@IBOutlet weak var collectionView: UICollectionView! //img: 77
@IBOutlet weak var pageControl: UIPageControl!
var thisWidth:CGFloat = 0
override func awakeFromNib() {
super.awakeFromNib()
thisWidth = CGFloat(self.frame.width)
collectionView.delegate = self
collectionView.dataSource = self
pageControl.hidesForSinglePage = true
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourCell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
self.pageControl.currentPage = indexPath.section
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
thisWidth = CGFloat(self.frame.width)
return CGSize(width: thisWidth, height: self.frame.height)
}
Ответ 2
Я не поклонник принятого ответа. Время от времени willDisplay cell
возвращает неправильную страницу для управления страницей в зависимости от взаимодействия пользователей.
Что я использую:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}
Это приведет к обновлению страницы после того, как пользователь закончит прокрутку, тем самым сделав currentPage
pageControl
более точным.
Ответ 3
Для более отзывчивого UIPageControl я предпочитаю использовать scrollViewDidScroll
и вычислять смещение относительно горизонтального центра scrollView.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offSet = scrollView.contentOffset.x
let width = scrollView.frame.width
let horizontalCenter = width / 2
pageControl.currentPage = Int(offSet + horizontalCenter) / Int(width)
}
Ответ 4
Ожидание scrollViewDidEndDecelerating
приводит к медленному обновлению UIPageControl
. Если вам нужен более scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)
пользовательский интерфейс, я предлагаю вместо этого реализовать scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)
.
Пример Swift 4, где каждый раздел просмотра коллекции представляет собой страницу:
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if let collectionView = scrollView as? ScoreCollectionView,
let section = collectionView.indexPathForItem(at: targetContentOffset.pointee)?.section {
self.pageControl.currentPage = section
}
}
Ответ 5
Ответ Люка был хорошим началом для меня, но у него было две проблемы: он не обновлялся часто (уже упоминалось в других ответах), но, самое главное, он не показывал правильную страницу для последнего элемента в моем представлении коллекции (горизонтально ориентированный) и он только переключил страницу, когда элемент почти покидал экран.
По первому вопросу, как отмечали другие, использование scrollViewDidScroll
обеспечило лучший опыт. Я беспокоился о проблемах с производительностью для частого вызова, но не заметил.
Что касается второй проблемы, для моего варианта использования найти индексную ячейку ячейки, которая находится в центре экрана, это лучшее решение. Имейте в виду, что если ваш вариант использования может поместить более двух ячеек на экран, это может потребоваться отрегулировать. Это потому, что ваша последняя ячейка никогда не дойдет до середины экрана. Я бы сказал, однако, что в этом случае использование UIPageControl
может быть не идеальным в любом случае.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let visibleRect = CGRect(origin: self.collectionView.contentOffset, size: self.collectionView.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
if let visibleIndexPath = self.collectionView.indexPathForItem(at: visiblePoint) {
self.pageControl.currentPage = visibleIndexPath.row
}
}
Ответ 6
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let visibleRect = CGRect(origin: self.cvImageListing.contentOffset, size: self.cvImageListing.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
if let visibleIndexPath = self.cvImageListing.indexPathForItem(at: visiblePoint) {
self.pageControl.currentPage = visibleIndexPath.row
}
}