Uicollectionview Scrolling in Both Directions

How can I change the scroll direction in UICollectionView?

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];

Note too that it seems to be fine to call this in prepareForLayout in your flow layout...

@interface LayoutHorizontalThings : UICollectionViewFlowLayout
@end

@implementation LayoutHorizontalBooks
-(void)prepareLayout
{
[super prepareLayout];

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

self.minimumInteritemSpacing = 0;
self.minimumLineSpacing = 0;
self.itemSize = CGSizeMake(110,130);
self.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
}

Creating UICollectionView which can scroll horizontally and vertically with Swift

Don't know what's wrong there on earth, but finally I got it work. Here you go:

import UIKit

class FeaturedViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UISearchResultsUpdating {

func updateSearchResults(for searchController: UISearchController) {
print("SeachController tapped.")
}

let firstCellId = "cellfirstCellIdId"

var appCategories: [AppCategory]?

override func viewDidLoad() {
super.viewDidLoad()
appCategories = AppCategory.sampleAppCategories()
collectionView?.backgroundColor = UIColor.clear
collectionView?.register(CategoryCell.self, forCellWithReuseIdentifier: firstCellId)
navigationItem.title = NSLocalizedString("Original", comment: "Original")
navigationController?.navigationBar.prefersLargeTitles = true

let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
navigationItem.hidesSearchBarWhenScrolling = true
self.navigationItem.searchController = searchController

}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: firstCellId, for: indexPath) as! CategoryCell
cell.appCategory = appCategories?[indexPath.item]
return cell
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

if let count = appCategories?.count {
return count
}
return 0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 300)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}

}

Here is the cell:

import  UIKit

class CategoryCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

var appCategory: AppCategory? {
didSet {
if let name = appCategory?.name {
firstChapterLabel.text = name
}
}
}

let secondCellId = "secondCellId"

let appsCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = UIColor.clear
collectionView.translatesAutoresizingMaskIntoConstraints = false
return collectionView
}()

let firstChapterLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
if UIDevice.current.userInterfaceIdiom == .phone {
label.font = UIFont.systemFont(ofSize: 14.0, weight: UIFont.Weight.medium)
} else {
label.font = UIFont.systemFont(ofSize: 20.0, weight: UIFont.Weight.medium)
}
label.textAlignment = .left
label.textColor = UIColor.darkGray
return label
}()

override init(frame: CGRect) {
super.init(frame: frame)

addSubview(appsCollectionView)
appsCollectionView.dataSource = self
appsCollectionView.delegate = self
appsCollectionView.register(AppCell.self, forCellWithReuseIdentifier: secondCellId)

appsCollectionView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 16).isActive = true
appsCollectionView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -16).isActive = true
appsCollectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 50).isActive = true
appsCollectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true

addSubview(firstChapterLabel)
firstChapterLabel.leftAnchor.constraint(equalTo: appsCollectionView.leftAnchor, constant: 16).isActive = true
firstChapterLabel.rightAnchor.constraint(equalTo: appsCollectionView.rightAnchor, constant: -16).isActive = true
firstChapterLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 24).isActive = true

}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = appCategory?.apps?.count {
return count
}
return 0

}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: secondCellId, for: indexPath) as! AppCell
cell.app = appCategory?.apps?[indexPath.item]
return cell

}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: frame.height, height: frame.height)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}

}

class AppCell: UICollectionViewCell {

var app: App? {
didSet {
if let imageName = app?.imageName {
photoImageView.image = UIImage(named: imageName)
}
}
}

let photoImageView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.layer.cornerRadius = 9
iv.layer.masksToBounds = true
iv.translatesAutoresizingMaskIntoConstraints = false
return iv
}()

override init(frame: CGRect) {
super.init(frame: frame)

addSubview(photoImageView)
photoImageView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 16).isActive = true
photoImageView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -16).isActive = true
photoImageView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -36).isActive = true
photoImageView.topAnchor.constraint(equalTo: self.topAnchor, constant: 36).isActive = true

}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

}

And the model stays as it was described in the question.

UICollectionView showing vertically even when scroll direction is set to horizontal?

I think you did not understand how UICollectionViewFlowLayout works.

Flow layout uses a line-based layout. What this means for you is that if you set the scroll direction to horizontal, then the cells will be laid out in a line form top to bottom until no more space is available and then move on to the next line.

You can verify this easily by changing the number of cell to something higher. (like 10?)


I recommend you watch this video to get a better understanding of how UICollectionView works.

UICollectionView. Only allow either vertical or horizontal scrolling at a time

You can set the isDirectionalLockEnabled to true on your scrollView:

If this property is true and the user begins dragging in one general
direction (horizontally or vertically), the scroll view disables
scrolling in the other direction.



Related Topics



Leave a reply



Submit