I installed this package https://github.com/hyperoslo/Lightbox ,but I do not know how to pass the index of my collectionView to display the desired picture , not the first one
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let controller = LightboxController(images: imagess)
controller.pageDelegate = self as? LightboxControllerPageDelegate
controller.dismissalDelegate = self as? LightboxControllerDismissalDelegate
controller.dynamicBackground = true
present(controller, animated: true, completion: nil)
}
In this case, I can change pictures but the first one always appears
I seem to have read everything but I did not find this important detail.
If i do like this :
let controller = LightboxController(images: [imagess[indexPath.row]])
I can only view one picture with the desired index but cannot change picture in gallery
Help pls :-)
You'll have to set start index to see the current image;
so try this;
let controller = LightboxController(images: imagess, startIndex:indexPath.row)
Related
I have a UICollectionViewCell who's data I want to access when tapped. The data will be used in another view controller... For instance, when I tap on a friend, the next viewcontroller presented will be a page with the tapped friends data.
Here is my didSelectItemAt IndexPath
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let layout = UICollectionViewFlowLayout()
let vc = JoinGroupChatController(collectionViewLayout: layout)
vc.selectedIndex = indexPath
let liveCell = LiveCell()
vc.descriptionLabel = liveCell.descriptionLabel.text
present(vc, animated: true, completion: nil)
}
In essence this is what I want to do however I need the indexPaths specific description label not the default liveCell label text.
I know I need to use the indexPath somewhere just not sure where / how.
Any suggestions?
replace
let liveCell = LiveCell()
with
let liveCell = collectionView.cellForItem(at: indexPath) as! LiveCell
I have an app which has two tabs. In the first BookVC tab, I use UICollectionViewController to show books and in didSelectItemAtIndexPath i call a function that push the BookDetailVC.
And in Bookmark tab, i want to show all books which was bookmarked and when user select certain book, i want to push BookDetailVC. I know it can be achieved by writing the same code as in BookVC. But i don't want to repeat the same code.
I'd tried to make BookmarkVC subclass of BookVC and ended up as showing the same book in both BookVC and BookmarkVC since i'm using the same one instance of UICollectionView from BookVC. Is there any way to override UICollectionView of BookVC or any other approach to solve. Sorry for my bad english. Thanks.
You are taking the wrong approach. The way you describe your bookmarks and your books View controller, it seems to me that they are identical, the only thing that changes is the content.
So, since collection views use data sources all you have to do is change the Data source based on whether you wanna show all books, or only the bookmarked ones.
Added code:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier :"secondViewController") as! UIViewController
self.present(viewController, animated: true)
I think you are doing wrong use just need to reload collection view based on which button is clicked take boolean
isBookMarkCliked:Bool
For Better Readablity create Model For Book
like
class Book {
var title: String
var author: String
var isBookMarked:Bool
init(title: String, author: String, isBookMarked:Bool) {
self.title = title
self.author = author
self.isBookMarked = isBookMarked
}
}
and declare two array globally with Book Model
arrForBooks:[Book] = []
arrForBookMarkedBooks:[Book] = []
Create CollectionViewDelegate methods using extension
extension YourClassVC: UICollectionViewDataSource,UICollectionViewDelegate
{
//MARK: UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
if isBookMarkClicked
{
return arrForBookMarkedBooks.count
}
return arrForBooks.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CellIdentifier", for: indexPath) as! YourCellClass
var currentBook:Book = nil
if isBookMarkClicked
currentBook = arrForStoreDetails[indexPath.row]
else
currentBook = arrForBookMarkedBooks[indexPath.row]
//Set data to cell from currentBook
return cell
}
//MARK: UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: false)
//Your code to push BookDetailVC
}
}
I have a UICollectionView that is populated by an array of images. I want to allow the user to tap on an image and preview it in a new UIViewController.
For some reason, didSelectItemAt method isn't working as expected. It doesn't throw an error, it gets called, just nothing happens really. Not sure what I do wrong here.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("did select item at was called")
let dashboardStoryboard = UIStoryboard(name: STORYBOARD_DASHBOARD, bundle:nil)
let destinationVC = dashboardStoryboard.instantiateViewController(withIdentifier: "PreviewPostImageVC") as! PreviewPostImageVC
destinationVC.selectedImage = arrayOfSelectedImages[indexPath.row]
self.navigationController?.pushViewController(destinationVC, animated: true)
}
I think Allen's comment points at the problem. If you're sure your method is being called (The print statement appears in the console) then the most likely problem is that self.navigationController is nil. With the optional chaining you're using, that call will fail silently if it's nil, which may or may not be what you want. Try changing it like this:
guard let navController = self.navigationController else {
print("Navigation Controller is nil!")
return
}
navController.pushViewController(destinationVC, animated: true)
Here is what I want to do (UI is showing down below), I want to perform different segue when I taped different cell in it. But I don't know what component I should use to get this done
I think to use the Collection View Controller, but it seems doest support static cells, I want to use Customized UIVIew to do this, but it couldn't be dragged to another VC in StoryBoard, should I adopt some sort of Protocols of something to do this?
Please answer in Swift
After been helped
Turns out I just need to show the ViewController and haven't need segue yet, so here is the code.
let categories: [(name: String, pic: String, identifier: String)] = [
("人物", "Wilson_head", "CharactersVC"),
("动物", "Pig", "MobsVC"),
("植物", "Bamboo_Patch", "PlantsVC"),
("食谱", "Crock_Pot_Build", "RecipesVC")
]
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let currentCategory = categories[indexPath.row]
let destVC: UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: currentCategory.identifier)
navigationController!.pushViewController(destVC, animated: true)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
if(indexPath.row == 0)
{
let objstory = self.storyboard?.instantiateViewController(withIdentifier: “your Story bord identifier”) as! Your View_ViewController
self.navigationController?.pushViewController(objstory, animated: true)
}
}
Collection View Controller doesn't support static cell.
But you can add static cell programmatically.
set your cell data and target(segue id) for each cell.
ex:
cellData[0].segue = "segueToHuman"
cellData[1].segue = "segueToAnimal"
add segues depend on your view controller(not on cell) like below:
create segue
segue setting
perform particular segue in didSelectItemAt indexPath
let segueID = cellData[indexPath.row].segue
performSegue(withIdentifier: segueID, sender: nil)
I have a collection view that scrolls horizontally and each cell pushes to a detail view upon a tap. When I load the app, I have it print the object at index. At first it will load the one cell it is supposed to. But when I scroll over one space it prints off two new ids, and then begins to associate the data of the last loaded cell with the one currently on the screen, which is off by one spot now. I have no clue how to resolve this, my best guess is there is some way to better keep up with the current index or there is something in the viewDidAppear maybe I am missing. Here is some code:
open var currentIndex: Int {
guard (self.collectionView) != nil else { return 0 }
return Int()
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ExpandCell", for: indexPath) as! ExpandingCollectionViewCell
let object = self.imageFilesArray[(indexPath).row] as! PFObject
cell.nameLabel.text = object["Name"] as! String
whatObject = String(describing: object.objectId)
print(whatObject)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let object = self.imageFilesArray[(indexPath as NSIndexPath).row]
guard let cell = collectionView.cellForItem(at: indexPath) as? ExpandingCollectionViewCell else { return }
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "EventDetailViewController") as! EventDetailViewController
nextViewController.lblName = nameData
nextViewController.whatObj = self.whatObject
self.present(nextViewController, animated:false, completion:nil)
}
Does anyone know a better way to set the current index so I am always pushing the correct data to the next page?
The data source that is setting the elements of the cell can keep count of index that can also be set as a property and can be used to retrieve back from the cell to get correct current index.
EventDetailViewController is your UICollectionViewController subclass I assume.
If this is correct then you need to implement on it:
A method that tells the collection how many items there are in the datasource.
//1
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1 // you only have 1 section
}
//2
override func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return array.count// this is the number of models you have to display... they will all live in one section
}
A method that tells the collection which cellView subclass to use for that given row.
-A method that populates the cell with it's datasource.
Follow this tutorial from which I extracted part of the code, they convey this core concepts pretty clearly.
Reusing, as per Apple's docs happens for a number of cells decided by UIKit, when you scroll up a little bit 2 or N cells can be dequed for reusing.
In summary, with this three methods you can offset your collection into skipping the one record that you want to avoid.
Happy coding!