I am getting multiple images from image picker save it into two collection view and make a view like this.
As you see,there was two collection which link to each other.Like when I tapped the second image at second collection view,the first collection view show the tapped image of second collection view.So,how to i link two collection view that are connected to each other.That was detail image selection view after I picked muliple images from gallery or camera.
Is this possible?
I will be very happy if somebody can give me a hand. :)
TODO NEXT : When I got that,I will going to add delete button at each image at second collection view.And add image "Add Button" after "img_4" for making user add more images into these two uicollection view.
When you select any item into second collection view you can show same image into first collection view this way:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
if collectionView == self.collectionView2{
collectionView1.scrollToItemAtIndexPath(indexPath, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
}
}
Below is complete example code for multiple collection views:
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet weak var collectionView1: UICollectionView!
#IBOutlet weak var collectionView2: UICollectionView!
let collectionViewAIdentifier = "CollectionViewACell"
let collectionViewBIdentifier = "CollectionViewBCell"
var imageArray = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
imageArray = [UIImage(named: "1.jpg")!, UIImage(named: "2.jpg")!, UIImage(named: "3.jpg")!, UIImage(named: "4.jpg")!, UIImage(named: "5.jpg")!, UIImage(named: "6.jpg")!, UIImage(named: "7.jpg")!, UIImage(named: "8.jpg")!, UIImage(named: "9.jpg")!, UIImage(named: "10.jpg")!, UIImage(named: "11.jpg")!, UIImage(named: "12.jpg")!, UIImage(named: "13.jpg")!]
print(imageArray)
collectionView1.delegate = self
collectionView2.delegate = self
collectionView1.dataSource = self
collectionView2.dataSource = self
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
if collectionView == self.collectionView1 {
let cellA = collectionView1.dequeueReusableCellWithReuseIdentifier(collectionViewAIdentifier, forIndexPath: indexPath) as! CollectionViewCell1
cellA.imageV.image = imageArray[indexPath.row]
return cellA
}
else {
let cellB = collectionView2.dequeueReusableCellWithReuseIdentifier(collectionViewBIdentifier, forIndexPath: indexPath) as! CollectionViewCell2
cellB.imageV.image = imageArray[indexPath.row]
return cellB
}
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageArray.count
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
if collectionView == self.collectionView2{
collectionView1.scrollToItemAtIndexPath(indexPath, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
}
}
}
Result:
Project Sample for more Info.
Related
I created the collection programmatically. Everything works perfectly. But now I need to replace a picture in a certain cell. How to identify the cell and get to the UIImage?
var imagesOfPaletes = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
if imagesOfPaletes == [] {
for i in 0...11 {
let palete = UIImage(named: "\(i)-0")!
imagesOfPaletes.append(palete)
}
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath as IndexPath)
let img2 = imagesOfPaletes[indexPath.item]
imageView2.image = img2
myCell.contentView.addSubview(imageView2)
return myCell
}
if you want to access a certain cell use "collection.cellForItem(at: inedexPath)" and then use the returned cell object to access the image.
So to access the image you can loop through cells subviews using "collectionCell.subViews" and check the type of the subView. check the following example:-
let collectionCell = UICollectionViewCell()
collectionCell.addSubview(UIImageView())
for subView in collectionCell.subviews {
if subView is UIImageView {
debugPrint("Ok")
}
debugPrint("subview is \(subView)")
}
I am trying to implement a collection view inside a table view cell.
My table view cell is a xib, and I've dragged a collection view into it.
Then, I created a class and xib for the collection view cell:
class MyCollectionViewCell: UICollectionViewCell {
var media: Image?
#IBOutlet weak var imageView: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func initialize(media: PostImage) {
self.media = media
if let url = media.url {
imageView.kf.setImage(with: URL(string: url))
}
}
}
And I've given the xib the class "MyCollectionViewCell" and also given it the identifier "MyCollectionViewCell".
Then, in my table view cell class, I have done the following:
class MyTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource {
var post: Post!
#IBOutlet weak var title: UILabel!
#IBOutlet weak var mediaCollectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
mediaCollectionView.delegate = self
mediaCollectionView.dataSource = self
let mediaCollectionViewCell = UINib(nibName: "MyCollectionViewCell", bundle: nil)
mediaCollectionView.register(mediaCollectionViewCell, forCellWithReuseIdentifier: "MyCollectionViewCell")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath as IndexPath) as? MyCollectionViewCell else {
fatalError("The dequeued cell is not an instance of MyCollectionViewCell.")
}
let media = post.images[indexPath.row]
cell.initialize(media: media)
return cell
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func initialize(post: Post) {
self.post = post
title.text = post.title
self.mediaCollectionView.reloadData()
}
}
The problem is, the collection view never shows when I run this. The title label text shows fine, but the collection view does not show, and I don't know what I'm doing wrong.
cellForItemAt doesn't even seem to get called, because when I add print("hello") at the top of the function, it never shows up in the console.
What am I doing wrong?
I think the problem is the height of the collection view is very small that it isn't shown.
Try to set the height for the table view cell:
func tableView(_: UITableView, heightForRowAt _: IndexPath) -> CGFloat {
return 100
}
where the 100 should be bigger than the collection view
here is my simplified code in my view controller
class WishListVC: UIViewController {
#IBOutlet weak var wishListCollectionView: UICollectionView!
private var products = [Product]()
private var selectedProduct : Product?
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - cell Delegate
extension WishListVC : ListProductCellDelegate {
func addToCartButtonDidTapped(at selectedIndexPath: IndexPath, collectionView: UICollectionView) {
guard let userOrder = userOrder else {return}
let selectedProduct = products[selectedIndexPath.item]
Order.addProductToOrderRealmDatabase(userOrder: userOrder, selectedProduct: selectedProduct)
wishListCollectionView.reloadData()
updateBadgeOnCartTabBar()
}
func stepperButtonDidTapped(at selectedIndexPath: IndexPath, stepperValue: Int, collectionView: UICollectionView) {
guard let userOrder = userOrder else {return}
let selectedProduct = products[selectedIndexPath.item]
if stepperValue > 0 {
Product.changeProductQuantityInRealmDatabase(selectedProduct: selectedProduct, quantity: stepperValue)
} else {
Order.removeProductFromOrderRealmDatabase(userOrder: userOrder, selectedProduct: selectedProduct)
Product.changeProductQuantityInRealmDatabase(selectedProduct: selectedProduct, quantity: 0)
}
wishListCollectionView.reloadData()
updateBadgeOnCartTabBar()
}
}
//MARK: - Collection View Data Source
extension WishListVC : UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return products.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WishListStoryboardData.CollectionViewIdentifiers.productSliderCell.rawValue, for: indexPath) as? ListProductCell else { return UICollectionViewCell()}
cell.productData = products[indexPath.item]
cell.delegate = self
cell.collectionView = wishListCollectionView
return cell
}
}
and here is the code for my collection view cell:
protocol ListProductCellDelegate {
func addToCartButtonDidTapped(at selectedIndexPath: IndexPath, collectionView : UICollectionView)
func stepperButtonDidTapped( at selectedIndexPath: IndexPath, stepperValue: Int, collectionView : UICollectionView)
}
class ListProductCell: UICollectionViewCell {
#IBOutlet weak var productImageViewAspectRatio: NSLayoutConstraint!
#IBOutlet weak var addToCartButton: UIButton!
#IBOutlet weak var stepper: GMStepper!
var collectionView : UICollectionView?
var delegate: ListProductCellDelegate?
var productData : Product? {
didSet {
updateUI()
}
}
#IBAction func addToCartButtonDidPressed(_ sender: UIButton) {
guard let collectionView = collectionView else {return}
guard let selectedIndexPath = collectionView.indexPathForView(view: sender) else {return}
self.delegate?.addToCartButtonDidTapped(at: selectedIndexPath, collectionView: collectionView)
}
#IBAction func stepperDidTapped(_ sender: GMStepper) {
guard let collectionView = self.collectionView else {return}
guard let selectedIndexPath = collectionView.indexPathForView(view: sender) else {return}
self.delegate?.stepperButtonDidTapped(at: selectedIndexPath, stepperValue: Int(sender.value), collectionView: collectionView)
}
private func updateUI() {
guard let product = productData else {return}
stepper.value = Double(product.quantity)
setLikeButton(product: product)
setCartAndStepperButton()
}
private func setCartAndStepperButton() {
guard let selectedProduct = productData else {return}
func showStepperButton(status: Bool) {
// to decide whether to show stepper or add to cart button.
stepper.isHidden = !status
stepper.isEnabled = status
addToCartButton.isHidden = status
addToCartButton.isEnabled = !status
}
if selectedProduct.quantity == 0 {
showStepperButton(status: false)
} else {
showStepperButton(status: true)
}
}
}
I don't understand why after I tap the stepper for the first time after the 'Add To Cart' disappear, the collection view will disappear.
I don't have collectionView.isHidden in my entire code, but I don't know why my collection view disappear like the file .gif below
http://g.recordit.co/NAEc36MbrM.gif
but if the stepper is already show with some stepper value more than 1, then it will make my collection view dissapear like the gif below
http://recordit.co/SLdqf1ztFZ.gif
the minimum stepper value is set to be 1.
If I change the collection view reload data wishListCollectionView.reloadData() in the stepperButtonDidTapped method above to be just reload data in certain cell only using wishListCollectionView.reloadItems(at: [selectedIndexPath]) the problem will be solved, but the stepper value seems it will be updated little slower, and it looks laggy.
I don't know how to trace the last line that will be executed so it makes my collection view disappears.
and if I reload the data in the main thread using:
DispatchQueue.main.async {
self.wishListCollectionView.reloadData()
}
it won't make the collection view disappear, but If I edit the cell index 4 it will affect the cell index 1 like gif here: http://g.recordit.co/6802BJDdtx.gif
I change the number in the fifth cell but it will automatically change the second cell.
Note to:
Use Xcode Ui Debugging tool and check if your collectionView is hidden or empty
Realm is realTime database ,any changes you make in database will be applied
on your arrays too(like products array)
The reason of stepper problem is becouse of :
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WishListStoryboardData.CollectionViewIdentifiers.productSliderCell.rawValue, for: indexPath) as? ListProductCell else { return UICollectionViewCell()}
and your using stepperButtonDidTapped delegete inside of cell.
declure your cells once and store them inside array,like below:
var cellArray:[ListProductCell]=[]
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if (cellArray.count > indexPath.row){
return cellArray[indexPath.row]
}else{
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WishListStoryboardData.CollectionViewIdentifiers.productSliderCell.rawValue, for: indexPath) as? ListProductCell else { return UICollectionViewCell()}
cell.productData = products[indexPath.item]
cell.delegate = self
cell.collectionView = wishListCollectionView
cellArray.append(cell)
return cell
}}
My case load get data success but not see data when reload.
This problem case born set Height in func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize is less than height cell on storyboard.
I have a Collection View with the ImageCollectionViewClass that I have defined as well as a class for the image. However the images in the collection view aren't changing with the indexPath and I can't work out why
class metricImage {
var featuredImage: UIImage!
init(featuredImage: UIImage!){
self.featuredImage = featuredImage
}
static func createImage() -> [metricImage] {
return [metricImage(featuredImage: UIImage(named: "prodOne.png")!), metricImage(featuredImage: UIImage(named: "prodTwo.png")!), metricImage(featuredImage: UIImage(named: "prodThree.png")!),metricImage(featuredImage: UIImage(named: "prodFour.png")!),metricImage(featuredImage: UIImage(named: "prodFive.png")!),metricImage(featuredImage: UIImage(named: "prodSix.png")!)]
}
}
class ImageCollectionViewCell: UICollectionViewCell
{
var images: metricImage! {
didSet{
updateUI()
}
}
#IBOutlet weak var featuredImageView: UIImageView!
private func updateUI() {
featuredImageView?.image! = images.featuredImage
}
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
if collectionView == prodCollectionView {
//print("collectionViewOne")
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("productCell", forIndexPath: indexPath) as! ImageCollectionViewCell
print(indexPath.item)
cell.images = self.prodImage[indexPath.item]
return cell
}
I have added some statements to make sure it enters where it needs to. I am new to swift so it may be trivial. Thank you in advance
Main Controller
class MainController: UIViewController,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
#IBOutlet weak var collectionView: UICollectionView!
let reUseCellName = "imgCell"
var counter = 1
override func viewDidLoad() {
super.viewDidLoad()
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reUseCellName, forIndexPath:indexPath) as! CellClass
cell.imageView.image = UIImage(named: "\(counter)")
cell.imgName = counter
counter++
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let newView = segue.destinationViewController as! showImage
let cell = sender as! CellClass
newView.imgNo = cell.imgName
}
I think its the way how your using them, try to define an array with images:
var arrayOfImages = ["1","2","3","4"]
And use it in cellForItemAtIndexPath :
cell.imageView.image = UIImage(named: arrayOfImages[indexPath.row])
Be sure to connect DataSoruce and Delegate for collectionView from connection inspector into your view controller to have the data loaded, and be sure to place the right image names.
Use the following code . the reason for the image not being displayed is the you have not mentioned the file extension with the image as jpg or png ... your counter value is "1" so app cannnot load the image name 1 without extension png or jpg
Use this code :
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reUseCellName, forIndexPath:indexPath) as! CellClass
cell.imageView.image = UIImage(named: "Complete image name with .png/.jpg")
cell.imgName = counter
counter++
return cell
}