Swift Link Image from Parse Array Using Segues to Secondviewcontroller

How to transfer image with Parse TableView

I think you have a few issues going on. First, if you're using a PFQueryTableViewController, objects is an array of PFObjects. This means you will want to either pass the entire PFObject to the destination view controller or you could pass individual properties.

Second, try the following in your table view controller to pass the whole object. In the destination view controller we can set the UILabel and UIImage.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "mySegue" {
// Get the new view controller using [segue destinationViewController]
var detailScene = segue.destinationViewController as! myController

// Pass the selected object to the destination view controller
if let indexPath = self.tableView.indexPathForSelectedRow() {
let row = Int(indexPath.row)
detailScene.currentObject = (objects?[row] as! PFObject)
}
}
}

Next, add the following to the top of your detail (destination) view controller

// Container to store the view table selected object
var currentObject : PFObject?

When the detail view controller loads, take the contents of currentObject and push the values into the appropriate labels and images so that they are displayed. Update your viewDidLoad() method to look like this.

override func viewDidLoad() {
super.viewDidLoad()

// Unwrap the current object
if let object = currentObject {
myLabelInViewController.text = object["someString"] as! String
myUIImageView.image = UIImage(data: object["someImageData"] as! NSData)
}
}

I'd highly recommend you check out this great tutorial on PFQueryTableViewControllers in Swift

Not able to pass array to second view controller using segue

var model = [News]() creates an empty array. You pass that to a new controller and then try to access the first element of this empty array. That's your issue.

Seems like there are no issues in passing it between controllers, you just try to access a nonexistent element. Plain old "index out of bounds" error, just like the error message told you. Add some objects and you will see that it works. If you want to check if it was passed at all (but that's a guarantee, no reason why it shouldn't), just do print(self.model), print(self.model.count) or print(self.model.first?.title) (this will print nil since the first element doesn't exist, again.)

How to transfer Image from tableview to second view

Second View controller:


class cropImageView:UIViewController{
@IBOutlet weak var cropImage: UIImageView!
var selectedImage : UIImage?
override func viewDidLoad() {
super.viewDidLoad()
self.cropImage.image = self.selectedImage //Assign selected Image here

}
}

PrepareForSegue method in FirstView controller be like:


override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "imageCropSegue"{
if let destination = segue.destinationViewController as? cropImageView {
if let profileIndex = self.parseTable.indexPathForSelectedRow()?.row {
var index = NSIndexPath(forRow: profileIndex, inSection: 0)

var cell = self.parseTable.cellForRowAtIndexPath(index) as! TableViewCell
//destination.cropImage.image = cell.cellImage.image //Change here

destination.selectedImage= cell.cellImage.image
}
}

}
}

Pass image from one view controller to another controller gives nil

You should use segue.destination not create a new one , like this

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

print("In here")

if segue.identifier == "showImage" {

let next = segue.destination as! showImageController

next.newImage = UIImage(named: imageArray[0])

}

}

TableView with Segues to Multiple Views

The logic that you need to implement is:

  1. Check the the segmentedIndex to know whether the user wants to see Upcoming or Showing.
  2. Load the tableView with movies per step 1.
  3. When the user taps on cell, use the segmentedIndex to identify whether you should a movie from the Upcoming or Showing array was chosen.
  4. Get the ID of that movie and send it to the respective DetailsViewController. Now that you have the movieID, use it to request the movie details from your database.

    func tableView(_ tableView:UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as? TableViewCell else { return UITableViewCell() }

    switch segmentedControl.selectedSegmentIndex {
    case 0:
    //handle the set up of Upcoming cells

    case 1:
    //handle the setup of Showing cells

    default:
    break
    }
    return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    switch segmentedControl.selectedSegmentIndex {

    case 0:
    let DetailViewUpcoming = self.storyboard?.instantiateViewController(withIdentifier: "DetailViewUpcoming") as! DetailViewUpcoming

    DetailViewUpcoming.init(forMovie: upcomingArray[indexPath.row].movieID)
    self.navigationController?.pushViewController(DetailViewUpcoming, animated: true)

    case 1:
    let DetailViewShowing = self.storyboard?.instantiateViewController(withIdentifier: "DetailViewShowing") as! DetailViewShowing

    DetailViewShowing.init(forMovie: showingArray[indexPath.row].movieID)
    self.navigationController?.pushViewController(DetailViewShowing, animated: true)

    default:
    break

    }
    }

    @IBAction func segmentedTapped(_ sender: Any) {
    tableView.reloadData()
    }

Inside DetailViewUpcoming and DetailViewShowing declare a variable for the movieID and add an initialiser

var movieID: String?

init(movieID:String){
self.movieID = movieID
}

Now when you load the view use the above movieID to request the movie details and assign them to properties as you see fit.

Passing Data from TableViewCell labels to a ViewController

You can create a JSON file with the data in your arrays and add it to your project:

{
"events":[
{
"name": "BTown Diner",
"details": "Free drink with meal after 12 AM",
"image": "btown"
},
{
"name": "Dunnkirk",
"details": "LADIES drink free",
"image": "dunn"
},
{
"name": "Chocolate Mousse",
"details": "10% off all ice cream!",
"image": "choco"
},
{
"name": "Lil Wayne",
"details": "Lil 500 concert",
"image": "lilwayne"
},
{
"name": "Annie",
"details": "an IU Theater Production",
"image": "default"
},
{
"name": "Campus Squad Social",
"details": "Bring your Squad to the Campus Squad Social",
"image": "default"
},
]
}

Create an Event class to encapsulate the data for a single event:

import UIKit

class Event {

let name: String!
let details:String!
let image: UIImage!

init(eventData: [String: String])
{
self.name = eventData["name"]
self.details = eventData["details"]
self.image = UIImage(named: eventData["image"]!)
}
}

Add a property of type Event to your DetailsViewController:

import UIKit

class DetailsViewController : UIViewController {

// To get the event from the main view controller
var event: Event!

@IBOutlet var detailsLabel: UILabel!
@IBOutlet var detailsImage: UIImageView!
@IBOutlet var detailsDesc: UILabel!

override func viewDidLoad() {

detailsLabel.text = event.name
detailsDesc.text = event.details
detailsImage.image = event.image
}
}

Add an array of class event to your main ViewController
Read the JSON data in ViewDidLoad and populate your events array
Implement prepareForSegue and set the event property of DetailsViewController with the selected event.

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet var tableView: UITableView!

// Created an Event class to store the event data
// Moved the hard coded data to Events.json
var events = [Event]()

override func viewDidLoad() {
super.viewDidLoad()

// Read the JSON data from main bundle
if let path = NSBundle.mainBundle().pathForResource("Events", ofType: "json") {
do {
let jsonData = try NSData(contentsOfFile: path, options: NSDataReadingOptions.DataReadingMappedIfSafe)
let parsedData = parseJSON(jsonData); // parse data to Swift dictionary
print(parsedData)
if let result = parsedData.result where parsedData.error == nil {

if let eventsData = result["events"] as? [[String : String]] {

for event in eventsData {

events.append(Event(eventData: event)) // Create an event from JSON data and add to the list
}
}

}
} catch {}
}
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return events.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell

cell.name.text = events[indexPath.row].name
cell.detail.text = events[indexPath.row].details
cell.photo.image = events[indexPath.row].image

return cell
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

if segue.identifier == "detailsSegue" {
guard let eventVC = segue.destinationViewController as? DetailsViewController,
let eventIndex = tableView.indexPathForSelectedRow?.row else {
return
}
// set the event to detail view controller
eventVC.event = events[eventIndex]

}
}

// Standard JSON parsing code
func parseJSON(data: NSData) -> (result: [String : AnyObject]?, error: NSError?) {

var parsingError: NSError? = nil
let parsedResult: [String : AnyObject]?
do {

parsedResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments) as? [String : AnyObject]
} catch let error as NSError {

parsingError = error
parsedResult = nil
}
return (parsedResult, parsingError)
}
}

Hope this helps!



Related Topics



Leave a reply



Submit