Im making an horizontal UICollectionView
, and inside UICollectionViewCell
i have scrollview and inside the scrollview i have an imageView.
The issue I'm having is that when i zoom-in the imageView,scrollView is taking all the cell size, so its not fitting to the image size height and width.thus by scrolling up and down the image disappear from scrollview, i have no idea whats going wrong in my code.
My ColectionViewCell
code:
class CollectionViewCell: UICollectionViewCell {
@IBOutlet var scrollView: UIScrollView!
@IBOutlet var ImageV: UIImageView!
}
CollectionView code :
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionViewCell
cell.scrollView.contentMode = UIViewContentMode.ScaleAspectFit
cell.scrollView.delegate = self
cell.ImageV.image = UIImage(named: array[indexPath.row])
cell.ImageV.contentMode = UIViewContentMode.ScaleAspectFit
cell.scrollView.minimumZoomScale = 1
cell.scrollView.maximumZoomScale = 4;
cell.scrollView.contentSize = cell.ImageV.frame.size
return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: self.collectionView.frame.size.width , height: self.collectionView.frame.size.height - 100)
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
let indexPath = NSIndexPath(forItem: Int(currentIndex), inSection: 0)
if let cell1 = self.collectionView.cellForItemAtIndexPath(indexPath) {
let cell = cell1 as! CollectionViewCell
let boundsSize = cell.scrollView.bounds.size
var contentsFrame = cell.ImageV.frame
if contentsFrame.size.width < boundsSize.width{
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2
}else{
contentsFrame.origin.x = 0
}
if contentsFrame.size.height < boundsSize.height {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2
}else{
contentsFrame.origin.y = 0
}
return cell.ImageV
}
return UIView()
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
currentIndex = self.collectionView.contentOffset.x / self.collectionView.frame.size.width;
oldcell = currentIndex - 1
let indexPath = NSIndexPath(forItem: Int(oldcell), inSection: 0)
if let cell1 = self.collectionView.cellForItemAtIndexPath(indexPath) {
let cell = cell1 as! CollectionViewCell
cell.scrollView.zoomScale = 0
}
}
Image preview: https://i.imgur.com/Gr2p09A.gifv
My project found here : https://drive.google.com/file/d/0B32ROW7V8Fj4RVZfVGliXzJseGM/view?usp=sharing
Well First lets start with UIViewController
that is holding your UICollectionView
:
Define a variable to hold the collection view layout:
var flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()
You will have to override viewWillLayoutSubviews
and this is going to handle the collectionView size.
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
flowLayout.itemSize = CGSize(width: view.frame.width, height:view.frame.height)
}
Also you will need to override viewDidLayoutSubviews
to handle the size of each new cell to set it to default size:
override func viewDidLayoutSubviews() {
if let currentCell = imageCollectionView.cellForItemAtIndexPath(desiredIndexPath) as? GalleryCell {
currentCell.configureForNewImage()
}
}
in ViewDidLoad
setup the collectionView to be horizontal with flow layout:
// Set up flow layout
flowLayout.scrollDirection = UICollectionViewScrollDirection.Horizontal
flowLayout.minimumInteritemSpacing = 0
flowLayout.minimumLineSpacing = 0
// Set up collection view
imageCollectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height), collectionViewLayout: flowLayout)
imageCollectionView.translatesAutoresizingMaskIntoConstraints = false
imageCollectionView.registerClass(GalleryCell.self, forCellWithReuseIdentifier: "GalleryCell")
imageCollectionView.dataSource = self
imageCollectionView.delegate = self
imageCollectionView.pagingEnabled = true
view.addSubview(imageCollectionView)
imageCollectionView.contentSize = CGSize(width: 1000.0, height: 1.0)
In your UICollectionView
method cellForItemAtIndexPath
load the image only without setting anything:
cell.image = UIImage(named: array[indexPath.row])
Now lets move to GalleryCell
class and to handle scrollView when zooming:
class GalleryCell: UICollectionViewCell, UIScrollViewDelegate {
var image:UIImage? {
didSet {
configureForNewImage()
}
}
var scrollView: UIScrollView
let imageView: UIImageView
override init(frame: CGRect) {
imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
scrollView = UIScrollView(frame: frame)
scrollView.translatesAutoresizingMaskIntoConstraints = false
super.init(frame: frame)
contentView.addSubview(scrollView)
contentView.addConstraints(scrollViewConstraints)
scrollView.addSubview(imageView)
scrollView.delegate = self
scrollView.maximumZoomScale = 4
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
internal func configureForNewImage() {
imageView.image = image
imageView.sizeToFit()
setZoomScale()
scrollViewDidZoom(scrollView)
}
public func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return imageView
}
public func scrollViewDidZoom(scrollView: UIScrollView) {
let imageViewSize = imageView.frame.size
let scrollViewSize = scrollView.bounds.size
let verticalPadding = imageViewSize.height < scrollViewSize.height ? (scrollViewSize.height - imageViewSize.height) / 2 : 0
let horizontalPadding = imageViewSize.width < scrollViewSize.width ? (scrollViewSize.width - imageViewSize.width) / 2 : 0
if verticalPadding >= 0 {
// Center the image on screen
scrollView.contentInset = UIEdgeInsets(top: verticalPadding, left: horizontalPadding, bottom: verticalPadding, right: horizontalPadding)
} else {
// Limit the image panning to the screen bounds
scrollView.contentSize = imageViewSize
}
}
I've tested it with example and it should solve your issue with scrollview and @Spencevail explained mostly why it's being caused !
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With