How to send collectionView data to another ViewController in swift3? - ios

I want to my collection View data (list.assets_id) want to parse DetailChannel
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
vedioId = id
}
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "detailChannel"{
let destinationVC = segue.destination as! DetailsChannel
destinationVC.vedio_id = vedioId
}
}
In my DetailChannel ,
override func viewDidLoad() {
super.viewDidLoad()
debugPrint("DetailsChannel:::::\(vedio_id)")
if let stringVideo = vedio_id {
print(stringVideo)
}
}
but didn't work my project and didn't call func prepare().How to slove?

I guess you've added segue from CollectionViewCell to
DetailChannel. Delete that segue.
Now add a segue from your CollectionViewController (not CollectionViewCell) to DetailChannel. If you don't know how to add it, here is the process:
First control-drag from the CollectionViewController to
DetailChannel and let go. visualize
here
Then select the segue and name it something meaningful to you (in your case detailChannel).
visualize here
Now inside your collectionView(_:didSelectItemAt:) method add this line:
performSegue(withIdentifier: "detailChannel", sender: self)
I hope your prepare(for:sender:) is now being called.

Related

How to save user's input in variable using delegate?

I'm making ios app. Please look my table view image below.
If you click add(+) button, you can add ENG word and its meaning in Korean(KOR) in each textfield.
After filling the textfield and click save button (it is located on right-top, "저장"), the word is added like the image below.
word is added
For example, the ENG is endless and the meaning(KOR) is "끝없는".
And, I want to use UIReferenceLibraryViewController .
If i click the cell of the list, i want to show its dictionary.
#IBAction func viewDictionary(_ sender: UITapGestureRecognizer) {
let engDictionaryWord = **engListWord**
let ViewController = UIReferenceLibraryViewController(term: engDictionaryWord)
self.present(ViewController, animated: true, completion: nil)
}
I want to use this method.
But, I don't know how to save my ENG input in engListWord.
In pic2 's swift file(addWordViewController.swift), there is prepare() method like this.
// This method lets you configure a view controller before it's presented.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
// Configure the destination view controller only when the save button is pressed.
guard let button = sender as? UIBarButtonItem, button === saveButton else {
os_log("The save button was not pressed, cancelling", log: OSLog.default, type: .debug)
return
}
let eng = engTextField.text ?? ""
let kor = korTextField.text ?? ""
// Set the meal to be passed to WordTableViewController after the unwind segue.
word = Word(eng:eng, kor:kor)
}
and viewDidLoad() method in addWordViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
engTextField.delegate = self
korTextField.delegate = self
// Set up views if editing an existing Word.
if let word = word{
engTextField.text = word.eng
korTextField.text = word.kor
}
// Do any additional setup after loading the view.
}
I don't know which variable i have to use.
There is other swift file in my project, If i misuploaded that codes above, please tell me! I will edit my question immediately.
Main.Storyboard
If i use GestureRecognizer, i made this code but I don't know it is right...
#IBAction func MyDictionary(_ sender: UITapGestureRecognizer) {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "viewDictionary", sender: indexPath)
}
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// I just made this identifier up, but create one yourself in the storyboard
if segue.identifier == "viewDictionary" {
// Define your vc
let libController = segue.destination as! UIReferenceLibraryViewController
// Define indexPath
let indexPath = sender as! IndexPath
// Set value in destination vc
libController.engWord = words[indexPath.row].eng
}
}
}
I think the way to go is to use the UITableViewDelegate method didSelectRowAtindexPath in the WordTableViewController (if that's the class with your table view).
A gestureRecognizer does not seem like something you want in your tableViewController as it has nice build in delegate methods to register user presses. Therefore, replace your viewDictionary(_:) function with the following:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "viewDictionary", sender: indexPath)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// I just made this identifier up, but create one yourself in the storyboard
if segue.identifier == "viewDictionary" {
// Define your vc
let libController = segue.destination as! UIReferenceLibraryViewController
// Define indexPath
let indexPath = sender as! IndexPath
// Set value in destination vc
libController.engWord = yourArrayOfEngWords[indexPath.row]
}
}
This will get your eng word of the cell you have pressed and save it to an attribute "engWord" that you then define in your UIReferenceLibraryViewController:
class UIReferenceLibraryViewController(){
var engWord: String = ""
// Rest your class properties and functions here...
}
Once it is set you can use it as you like after the segue has been performed :=)

Xcode: Passing Information from UITableViewController to UIViewController

I have a UIViewController which should show me DetailInformations depending on what Cell was pressed in the UITableViewController.
For the moment I am passing them through a sequel:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "show" {
var ctrl = segue.destination as! DetailViewController
ctrl.information = _informationList[id]
}
}
The id variable is set through:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
id = indexPath.row
}
Now in my UIViewController I change the information with:
override func viewDidLoad() {
super.viewDidLoad()
setInformation(i: information)
}
Now my problem is, that if I press, lets say cell 2. It switches to the ViewController and shows Information of cell 1. Than I go back to the tableview and I press cell 3. Then it shows me cell 2.
In short, it seems that the viewController is loaded (with the last information), before it sets the new information.
Is there any better way to solve this?
Try using indexPathForSelectedRow in prepareForSegue as of it looks like that you have created segue from UITableViewCell to the Destination ViewController so that prepareForSegue will call before the didSelectRowAt.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "show" {
var ctrl = segue.destination as! DetailViewController
if let indexPath = self.tableView.indexPathForSelectedRow {
ctrl.information = _informationList[indexPath.row]
}
}
}
I am assuming based on what you are describing is that you used a segue in your Storyboard to link directly from the cell to the detail view controller. This is not what you want to do, as mentioned earlier, because you don't get the order of events you would expect. You could use the delegation design pattern for this, but assuming you want to stick with segues you need to make the "show" segue from the table VC itself to the detail VC. You then manually call the segue from the tableView didSelectRowAt code.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
id = indexPath.row
performSegue(withIdentifier: "show", sender: self)
}
Finally, you could then use an unwind segue when you come back to catch any data changes initiated in the detail VC.

prepare function not called - swift 3

I have a collection view. each item should pass data to second view, in other world I want to pass current view to second view by navigationController.
class GroupsViewController: UIViewController ,UICollectionViewDataSource, UICollectionViewDelegate {
....
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// handle tap events
var group = self.items[indexPath.item]
var cat_title = group.cat_title
self.navigationController!.pushViewController(self.storyboard!.instantiateViewController(withIdentifier: "GroupSubOneTableViewController") as UIViewController, animated: true)
}
....
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("ooopps")
if (segue.identifier == "GroupSubOneTableViewController") {
let navController = segue.destination as! UINavigationController
let detailController = navController.topViewController as! GroupSubOneTableViewController
//detailController.currentId = nextId!
print("selected GroupSubOneTableViewController")
}
}
but in console log doesn't show anything!
You are mixing here two thing perfomSegue and pushViewController. perform​Segue(with​Identifier:​sender:​)
is called when you perform a segue using performSegue. So create one segue from your SourceVC to DestinationVC.
If you want to go with pushViewController then simply type cast UIViewController to your ViewController pass the data.
let vc = self.storyboard!.instantiateViewController(withIdentifier: "GroupSubOneTableViewController") as! GroupSubOneTableViewController
//pass vaue
vc.passStr = "Hello"
self.navigationController?.pushViewController(vc, animated: true)
It's not called because pushViewController doesn't perform a segue.
You need to call performSegue(withIdentifier: "GroupSubOneTableViewController", sender: self) instead of pushViewController.
Of course, you'll also need to set this up in your storyboard.

Passing value to another ViewController upon selecting cell in UICollectionView

I want to select a username from a UICollectionView, and pass that string to another view.
I can select the cell using "didSelectRowAtIndexPath". However the prepareForSegue function runs before my selection is set, and the segue passes the initial value.
I can't figure out how to get the index value in the prepareForSegue overide. If it were a UITableView, I think I could use indexPathForSelectedRow.
Here's what I have:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
selectedUsername = userNames[indexPath.row]
selectedRow = indexPath.row
println ("Cell \(indexPath.row) selected")
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "userSelectSegue") {
let nextVC = segue.destinationViewController as ViewController;
nextVC.passedUsername = userNames[selectedRow]
println("prepareForSegue")
}
}
Running this always passes userNames[0]
The output window Prints:
prepareForSegue
Cell 2 selected
EDIT 1:
I basically think I want the following tableview code, but I can't get it working for UICollectionView (i.e. I can't get the cell number):
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "userSelectSegue") {
let nextVC = segue.destinationViewController as ViewController;
let indexPath = UserSelectCollection.indexPathForSelectedRow()
nextVC.passedUsername = userNames[indexPath.row]
}
}
Here's How I solved it:
I deleted the segue connecting the collection cell to the second view controller
I created another segue between the two view controllers (called the identifier "userSelectSegue")
Added a performSegueWithIdentifier call to the didSelectItemAtIndexPath
Here's the code:
var userNames = ["Bob", "Sally", "Mike", "Mary", "James"]
var selectedRow = 0
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath.row
self.performSegueWithIdentifier("userSelectSegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "userSelectSegue") {
let nextVC = segue.destinationViewController as ViewController;
nextVC.passedUsername = userNames[selectedRow]
}
}
This is the general behavior of the iOS. What i implement is in this case is. Do not override the method didSelectRowAtIndexPath. When you tap on any cell, then in the function prepareForSegue. You can get the cell in the sender object. From that cell get the selected item. Get the indexPath.item. After that get the object from the array and pass it to the next view controller.

Sending information to detail view upon CollectionViewCell selection

I'm trying to send information to a detail view about the cell selected upon selection. Right now, prepareForSegue runs prior to the collection view delegate method I'm using. This results in me sending the information of the previous cell selection and not the current one.
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
collectionView.deselectItemAtIndexPath(indexPath, animated: true)
nextScreenRow = indexPath.row
self.performSegueWithIdentifier("toDetails", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "toDetails" {
let vc = segue.destinationViewController as HistoryDetailsViewController
vc.postcard = postcards[nextScreenRow]
}
}
Two things. If the segue is made from the cell, then you shouldn't be calling performSegue in code; selecting the cell will trigger the segue with no code. Secondly, when you connect a segue this way, you don't need to implement didSelectItemAtIndexPath at all (but it's ok if you just want to call deselectItemAtIndexPath). There's no need for it; you can do everything you need to in prepareForSegue. The cell will be the sender, so can just do this,
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "toDetails" {
let cell = sender as UICollectionViewCell
let indexPath = collectionView!.indexPathForCell(cell)
let vc = segue.destinationViewController as HistoryDetailsViewController
vc.postcard = postcards[indexPath.item]
}
}

Resources