UICollectionView won't center - ios

I have a fullscreen UICollectionView with cells. I have checked the width and height, and the view covers the entire screen. However, when I enabled paging, the view was no longer centered. How can I set the center of the cell or the collection view, so it does take the entire screen?
import UIKit
class ShowPictures: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
var PICTURES: [Picture] = []
#IBAction func swipeAway(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
override var prefersStatusBarHidden: Bool {
return true
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
private func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return UIScreen.main.bounds.size
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return self.PICTURES.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let item: Messages.MessageAdapter.Item.Picture = self.PICTURES[indexPath.section]
let cell: Cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! Cell
return cell
}
#IBAction func CloseController(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}
class Cell: UICollectionViewCell, UIScrollViewDelegate {
#IBOutlet weak var _image: UIImageView!
#IBOutlet weak var _scroll: UIScrollView!
override func layoutSubviews() {
self._scroll.delegate = self
self._scroll.zoomScale = CGFloat(integerLiteral: 1)
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return self._image
}
}

Add the following delegate method to remove the inset:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return .zero
}

Related

swift 4 set cells with different heights and width on the same UICollectionView vertical flow

I'm trying to make images grid like the below image
I tried the below code
import UIKit
class ViewController: UIViewController,UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var collectionViw: UICollectionView!
var widthss = [59.0,59.0,59.0,121.0,59.0,59.0,59.0,59.0,59.0,59.0,28.0,28.0,59.0,59.0,] as [CGFloat]
var heights = [36.0,36.0,36.0,76.0,36.0,76.0,36.0,36.0,36.0,76.0,36.0,36.0,36.0,76.0,] as [CGFloat]
override func viewDidLoad() {
super.viewDidLoad()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return heights.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! UICustomCollectionViewCell
// Customize cell height
cell.frame = CGRect(x: cell.frame.origin.x, y: cell.frame.origin.y , width: widthss[indexPath.row], height: heights[indexPath.row])
return cell
}
}
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: widthss[indexPath.row], height: heights[indexPath.row])
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {return 1.0
}
func collectionView(_ collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 1.0
}}
at the end, i found the result like the below image,
what I need is to make the collection view cells like the first image
Anyone have an idea where is my mistake
thanks in advance

How to properly add spacing between collection view cells?

I'm currently trying to set spacing between my collection view cells. The issue is every time I scroll horizontally the cell does not reset back to where is should be. I'm using this library for the collection view cell animation: https://github.com/KelvinJin/AnimatedCollectionViewLayout.
Please Look at image bellow!
Here is my code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Turn on the paging mode for auto snaping support.
collectionView?.isPagingEnabled = true
if let layout = collectionView?.collectionViewLayout as? AnimatedCollectionViewLayout {
layout.scrollDirection = direction
layout.animator = animator?.0
}
dismissGesture.direction = direction == .horizontal ? .down : .left
}
extension ImageCollectionViewController: UICollectionViewDelegateFlowLayout {
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return Int(Int16.max)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let c = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath)
if let cell = c as? SimpleCollectionViewCell {
let i = indexPath.row % vcs.count
let v = vcs[i]
cell.bind(color: v.0, imageName: v.1)
cell.clipsToBounds = animator?.1 ?? true
}
return c
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
guard let animator = animator else { return view.bounds.size }
return CGSize(width: view.bounds.width / CGFloat(animator.2), height: view.bounds.height / CGFloat(animator.3))
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return .zero
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
}
Also here are images showing what happens:

Why insetForSectionAt UICollectionView delegate not calling in iOS Swift 3?

I have problem with UICollectionView Delegation. Because insetForSectionAt delegate never call.
So see this code and help me to fix this :
import UIKit
class GalleryCollectionViewController: UICollectionViewController {
var dataSourceArr:Array<UIImage>!
override init(collectionViewLayout layout: UICollectionViewLayout) {
super.init(collectionViewLayout: layout)
collectionView?.collectionViewLayout = layout
collectionView!.register(GalleryCollectionViewCell.self, forCellWithReuseIdentifier: "cell")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if dataSourceArr.count != 0 {
return dataSourceArr.count
}
return 0
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! GalleryCollectionViewCell
cell.imageView.image = dataSourceArr[indexPath.row]
return cell
}
// MARK: UICollectionViewDelegate
func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,minimumLineSpacingForSectionAt section: Int) -> CGFloat{
return 0;
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0;
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width:collectionView.bounds.size.width/4 , height: collectionView.bounds.size.width/4)
}
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets{
return UIEdgeInsetsMake(0,0,0,0)
}
}
You need to inherit from UICollectionViewDelegateFlowLayout, e.g.
class GalleryCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout

UIcollectionview cell issue Swift

I have a simple collectionview controller like this:
class ViewController1: UICollectionViewController{
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView?.delegate = self
self.collectionView?.dataSource = self
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "P", for: indexPath)
return cell
}
}
In the cell there is only an uiimageview and it has this constraints:
My problem is this:
when I execute this code on iPhone 6 simulator I get this (right way):
but when I execute this code on iPhone 5 simulator I get this (wrong way: the imageview starts before the screen on the left and the width and height are wrong respect to the constraints):
I am going crazy for this problem but I dont be able to solve.
Can you help me?
You need to extend your ViewController1 to conform to UICollectionViewDelegateFlowLayout protocol. And implement methods to set size for each collection view cell like so:
class ViewController1: UICollectionViewController, UICollectionViewDelegateFlowLayout {
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView?.delegate = self
self.collectionView?.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print(self.collectionView!.frame)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "P", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.collectionView!.frame.size.width, height: 120.0)
}
}
It has hard coded values, but you should get the idea. Collection View width should be the max size for each item, so they won't get outside the box.

uicollectionviewcell labels misaligned after reload

I tried following code to render simple collection view on screen.
But subviews in contentview do not algin properly
I am coding in swift 2.3 with Xcode 7.3.1
Whys is this happening?
Here is the code
import Foundation
class CustomerOverdueViewController : BaseViewController , UICollectionViewDelegateFlowLayout {
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var lblTotalOverdue: UILabel!
#IBOutlet weak var lblInvestedFunds: UILabel!
#IBOutlet weak var segmentedControl: UISegmentedControl!
var rangeArray = NSArray()
var selectedOverdueIndex = 0
var selectedColor = UIColor()
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Customer Overdue"
}
#IBAction func segValueChanged(sender: UISegmentedControl) {
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 6
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let reuseIdentifier = String("CustomerOverdueCollectionViewCell")
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CustomerOverdueCollectionViewCell
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
return CGSize(width: collectionView.frame.size.width/2 - 10, height: collectionView.frame.size.height/3 - 10)
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets
{
return UIEdgeInsets(top: 5, left: 5, bottom: 0, right: 5)
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
{
return 10.0
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat
{
return 10.0
}
}
Finally I got the solution
Override layoutSubviews in Custom Cell
override func layoutSubviews() {
super.layoutSubviews()
self.layoutIfNeeded()
}
and add following lines in cellForItemAtIndexpath
cell.setNeedsLayout()
cell.layoutIfNeeded()
It seems that in the initial call the data is used when the table is first drawn (from ViewWillLoad). However when you refresh the data, the constraints are not recalculated.
Normally this is done via setNeedsLayout and/or layoutIfNeeded
You can try:
[view layoutIfNeeded];

Resources