Passing data with segue in the tableViewCell - ios

I want to passing data with segue in the tableViewCell,from BulletinBoadrViewController to BbDetailViewController
class BulletinBoadrViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var bulletinBoards = [BulletinBoard]()
override func viewDidLoad() {
super.viewDidLoad()
bulletinBoards = BulletinBoard.downloadAllBulletinBoard()
self.tableView.reloadData()
tableView.estimatedRowHeight = tableView.rowHeight
tableView.rowHeight = UITableViewAutomaticDimension
tableView.separatorStyle = .none
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return bulletinBoards.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! BulletinBoardTableViewCell
let bulletinBoard = bulletinBoards[indexPath.row]
cell.bulletinBoard = bulletinBoard
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "gotodetail", sender: indexPath)
print("Row \(indexPath.row)selected")
}
func prepareForSegue(segue: UIStoryboardSegue, sender: Any!) {
if segue.identifier == "gotodetail" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let destVC = segue.destination as! BdDeatilViewController
let new = bulletinBoards[indexPath.row]
destVC.bulletinBoard = new
}
}
}
and it's BdDeailViewController
class BdDeatilViewController:UIViewController {
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var timeLabel: UILabel!
#IBOutlet weak var contentLabel: UITextView!
#IBAction func backtobb(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
var x = [BulletinBoard]()
var bulletinBoard : BulletinBoard!{
didSet{
self.updateUI()
}
}
func updateUI() {
timeLabel.text = bulletinBoard.time
titleLabel.text = bulletinBoard.title
contentLabel.text = bulletinBoard.content
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
}
and tableViewCell's data is taking from local json file, it's BulletinBoard code
class BulletinBoard {
var title:String?
var time:String?
var content:String?
init(title:String,time:String,content:String) {
self.title = title
self.time = time
self.content = content
}
init(bulletinBoardDictionary:[String:Any]) {
self.title = bulletinBoardDictionary["title"] as? String
self.time = bulletinBoardDictionary["time"] as? String
self.content = bulletinBoardDictionary["content"] as? String
}
static func downloadAllBulletinBoard() -> [BulletinBoard] {
var bulletinBoards = [BulletinBoard]()
//get the json data from the file
let jsonFile = Bundle.main.path(forResource: "BulletinBoardData", ofType: "json")
let jsonFileURL = URL(fileURLWithPath: jsonFile!)
let jsonData = try? Data(contentsOf: jsonFileURL)
//turn the json data into foundation objects (bulletinBoards)
if let jsonDictionary = NetworkService.parseJSONFromData(jsonData) {
let bulletinBoardDictionaries = jsonDictionary["BulletinBoard"] as! [[String:Any]]
for bulletinBoardDictionary in bulletinBoardDictionaries {
let newBulletinBoard = BulletinBoard(bulletinBoardDictionary: bulletinBoardDictionary)
bulletinBoards.append(newBulletinBoard)
}
}
return bulletinBoards
}
}
Finally,it's my StoryBoard
https://i.stack.imgur.com/JcgdH.png1
Can anyone solve my problem?Thanks!

I think you should retrieve indexPath from sender in prepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: Any!) {
if segue.identifier == "gotodetail" {
if let indexPath = sender as? IndexPath {
let destVC = segue.destination as! BdDeatilViewController
let new = bulletinBoards[indexPath.row]
destVC.bulletinBoard = new
}
}
}
and update the UI in the viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
self.updateUI()
}

Related

Sending data to another view controller but every data i send is nil or empty

all.
I am having a problem sending data.
I try to send data from AgentDetailVC to AbilitiesDetailsVC. But i cant. Every data i try to send is nil or empty string.I had managed to send before AgentListVC to AgentDetailsVC. Can y'all examine my code and help me please? Thank you a lot.
This is my AgenListVC.
import UIKit
class AgentListVC: UIViewController {
var agentsReference = ValorantReferenceApp().agents
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
self.tableView.rowHeight = 100
// tableView.separatorStyle = .none
tableView.delegate = self
tableView.dataSource = self
super.viewDidLoad()
configureNavigationBar()
}
//MARK: - Configure Navigation Bar
func configureNavigationBar() {
self.navigationController?.navigationBar.prefersLargeTitles = true
if var textAttributes = navigationController?.navigationBar.titleTextAttributes {
textAttributes[NSAttributedString.Key.foregroundColor] = UIColor.red
navigationController?.navigationBar.titleTextAttributes = textAttributes
}
}
}
//MARK: - Table View Methods
extension AgentListVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return agentsReference.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! AgentCellVC
let agent = agentsReference[indexPath.row]
cell.agentNameLAbel.text = agent.name
cell.agentImageview.image = agent.iconAgent
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "toSecondVC", sender: nil)
// tableView.deselectRow(at: indexPath, animated: true)
}
//MARK: - Prepare Segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! AgentDetailVC
if let indexPath = tableView.indexPathForSelectedRow {
let agent = agentsReference[indexPath.row]
destinationVC.agentDetailVariables.choosenFlagImage = agent.agentFlagImage
destinationVC.agentDetailVariables.choosenAgentIconImage = agent.iconAgent
destinationVC.agentDetailVariables.choosenAgentType = agent.type.rawValue
destinationVC.agentDetailVariables.choosenAgentName = agent.name
destinationVC.choosenAgentAbilities = agent.abilities
destinationVC.agentDetailVariables.choosenAgentAbilitiesImages = agent.agentAbilitiesImage
destinationVC.choosenAgentVideoLink = agent.skillAbilitiesLink
}
}
}
This is my AgentDetailVC.
import UIKit
class AgentDetailVC: UIViewController {
#IBOutlet var typeLabel: UILabel!
#IBOutlet var characterImageView: UIImageView!
#IBOutlet var flagImageView: UIImageView!
#IBOutlet var tableView: UITableView!
#IBOutlet var agentTypeImageView: UIImageView!
var agentDetailVariables = AgentDetailVariables()
var agentsReference = ValorantReferenceApp().agents
var choosenAgentAbilities = [String]()
var viewController = AbilitiesDetailsViewController()
var choosenAgentVideoLink = [String]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
viewLoad()
print(choosenAgentAbilities)
}
//MARK: - ViewLoad Function.
func viewLoad() {
flagImageView.image = agentDetailVariables.choosenFlagImage
characterImageView.image = agentDetailVariables.choosenAgentIconImage
typeLabel.text = agentDetailVariables.choosenAgentType
title = agentDetailVariables.choosenAgentName
tableView.rowHeight = 65
tableView.separatorStyle = .none
agentTypeImageView.image = UIImage(named: "\(agentDetailVariables.choosenAgentType)")
// print(agentDetailVariables.choosenAgentVideoLink)
}
}
//MARK: - TableView Methods
extension AgentDetailVC : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return choosenAgentAbilities.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath) as! AgentDetailsCellVC
let agentAbilities = choosenAgentAbilities[indexPath.row]
let skillImages = agentDetailVariables.choosenAgentAbilitiesImages[indexPath.row]
print(agentAbilities)
cell.skillNameLabel.text = agentAbilities
cell.skillImageView.image = skillImages
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "toYoutubeVideos", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toYoutubeVideos" {
let destinationVC = segue.destination as! AbilitiesDetailsViewController
if let indexPath = tableView.indexPathForSelectedRow {
let agent = agentsReference[indexPath.row]
let link = choosenAgentVideoLink[indexPath.row]
print(link)
destinationVC.agentAbilitiesVideoURL = link
destinationVC.choosenAgentSkillName = choosenAgentAbilities[indexPath.row]
}
}
}
}
This is my AbilitiesDetailsViewController
import UIKit
import AVKit
import AVFoundation
import MediaPlayer
import MobileCoreServices
import YoutubePlayer_in_WKWebView
class AbilitiesDetailsViewController: UIViewController, AVPlayerViewControllerDelegate {
#IBOutlet var skillDetailsLabel: UILabel!
#IBOutlet var skillNameLabel: UILabel!
#IBOutlet var heroIconImageView: UIImageView!
var agentAbilitiesVideoURL = ""
var choosenAgentSkillName = ""
override func viewDidLoad() {
skillNameLabel.text = choosenAgentSkillName
super.viewDidLoad()
//playAbilitiesVideos()
}
#IBAction func playVideoUsingURL(_ sender: Any) {
playGlobalVideo()
}
func playGlobalVideo() {
guard let videoURL = URL(string: agentAbilitiesVideoURL ?? "sad") else {
return
}
let player = AVPlayer(url: videoURL)
let vc = AVPlayerViewController()
vc.player = player
present(vc, animated: true) {
player.play()
}
}
func playAbilitiesVideos() {
let player = AVPlayer(url: URL(string: "https://assets.contentstack.io/v3/assets/bltb6530b271fddd0b1/bltf4e7a6525fe6ec42/625f2c7cfd9afd4b1fe300ee/C-Prowler_video.mp4")!)
let controller = AVPlayerViewController()
present(controller, animated: true) { }
controller.player = player
addChild(controller)
view.addSubview(controller.view)
controller.view.frame = CGRect(x: 50 , y: 50, width: 300, height: 300)
controller.player = player
controller.showsPlaybackControls = true
player.isClosedCaptionDisplayEnabled = false
player.play()
}
}
This is my struct.
struct Agent: Hashable{
let name: String
let type: AgentType
let origin: String
let abilities: [String]
let iconAgent : UIImage
let agentFlagImage : UIImage
let agentAbilitiesImage: [UIImage]
let skillAbilitiesLink: [String]
}
enum AgentType:String{
case controller = "Controller"
case sentinel = "Sentinel"
case initiator = "Initiator"
case duelist = "Duelist"
}
This is my Agents.
struct ValorantReferenceApp {
static var agentIconImages = AgentIconImages()
static var agentFlagImages = AgentFlagImages()
static var agentAbilitiesImages = AgentAbilitiesImages()
var agents: [Agent] = [
Agent(name: "Brimstone", type: .controller, origin: "United States", abilities: ["Incendiary",
"Stim Beacon",
"Sky Smoke",
"Orbital Strike"],
iconAgent: agentIconImages.iconBrimstone!,
agentFlagImage: agentFlagImages.flagBrimstone!,
agentAbilitiesImage: agentAbilitiesImages.abilitiesBrimstone, skillAbilitiesLink:
["https://assets.contentstack.io/v3/assets/bltb6530b271fddd0b1/blte2b9eb1923ef64fa/5ecad7d0f5bd13348a6cac75/Brimstone_Q_v001_web.mp4",
"https://assets.contentstack.io/v3/assets/bltb6530b271fddd0b1/bltc34c3d692ea83f41/5ecad7d0177c51692beb1fe4/Brimstone_C_v001_web.mp4",
"https://assets.contentstack.io/v3/assets/bltb6530b271fddd0b1/bltcf4359fed083686b/5ecad7d198f79d6925dbee07/Brimstone_E_v001_web.mp4",
"https://assets.contentstack.io/v3/assets/bltb6530b271fddd0b1/blt3d19d83ba51eb18f/5ecad7d297b46c1911ad1868/Brimstone_X_v001_web.mp4"
])
]
In AgentDetailVC you have this code:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "toYoutubeVideos", sender: nil)
}
When the user selects a Row, the first thing you've done is deselect that row. You then call performSegue.
In prepare(for segue:...) you do this:
if let indexPath = tableView.indexPathForSelectedRow {
So -- tableView.indexPathForSelectedRow will always be nil because you just set it to nil.
Call .deselectRow after you perform the segue.

How can I take the sum of table view cells' data in Swift?

I'm trying to add up all of the amount data and send to a different table view cell. I think I need to convert String to Double before I can do this, but I'm not sure how to do this either. Does anyone know how you can take the sum of data and present it somewhere else? I'm very new to swift and am having trouble figuring out where I need to write this code.
import Foundation
struct Income: Codable {
var name: String
var amount: String
init(name: String, amount: String) {
self.name = name
self.amount = amount
}
static let DocumentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("incomes").appendingPathExtension("plist")
static func loadSampleIncomes() -> [Income] {
return [
Income(name: "Main Income", amount: "0"),
Income(name: "Secondary Income", amount: "0"),
Income(name: "Interest Income", amount: "0")]
}
static func saveToFile(incomes: [Income]) {
let propertyListEncoder = PropertyListEncoder()
let codedIncomes = try? propertyListEncoder.encode(incomes)
try? codedIncomes?.write(to: ArchiveURL, options: .noFileProtection)
}
static func loadFromFile() -> [Income]? {
guard let codedIncomes = try? Data(contentsOf: ArchiveURL) else { return nil }
let propertyListDecoder = PropertyListDecoder()
return try? propertyListDecoder.decode(Array<Income>.self, from: codedIncomes)
}
}
import UIKit
class IncomeTableViewController: UITableViewController {
var incomes: [Income] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView(frame: CGRect.zero)
if let savedIncomes = Income.loadFromFile() {
incomes = savedIncomes
} else {
incomes = Income.loadSampleIncomes()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
// table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return incomes.count
} else {
return 0
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "incomeCell", for: indexPath) as! IncomeTableViewCell
let income = incomes[indexPath.row]
cell.update(with: income)
cell.showsReorderControl = true
return cell
}
// MARK: - Table view delegate
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .delete
}
override func tableView(_ tableView: UITableView, commit
editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath:
IndexPath) {
if editingStyle == .delete {
incomes.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: . automatic)
Income.saveToFile(incomes: incomes)
}
}
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
let movedIncome = incomes.remove(at: fromIndexPath.row)
incomes.insert(movedIncome, at: to.row)
tableView.reloadData()
}
#IBAction func editButtonTapped(_ sender: UIBarButtonItem) {
let tableViewEditingMode = tableView.isEditing
tableView.setEditing(!tableViewEditingMode, animated: true)
}
// Navigation
#IBAction func unwindToIncomeTableView(segue:UIStoryboardSegue) {
guard segue.identifier == "saveIncomeUnwind",
let sourceViewController = segue.source as? AddEditIncomeTableViewController,
let income = sourceViewController.income else { return }
if let selectedIndexPath = tableView.indexPathForSelectedRow {
incomes[selectedIndexPath.row] = income
tableView.reloadRows(at: [selectedIndexPath],
with: .none)
} else {
let newIndexPath = IndexPath(row: incomes.count, section: 0)
incomes.append(income)
tableView.insertRows(at: [newIndexPath], with: .automatic)
}
Income.saveToFile(incomes: incomes)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "EditIncome" {
let indexPath = tableView.indexPathForSelectedRow!
let income = incomes[indexPath.row]
let navController = segue.destination as! UINavigationController
let addEditIncomeTableViewController = navController.topViewController as! AddEditIncomeTableViewController
addEditIncomeTableViewController.income = income
}
}
}
import UIKit
class AddEditIncomeTableViewController: UITableViewController {
#IBOutlet weak var saveButton: UIBarButtonItem!
#IBOutlet weak var incomeNameTextField: UITextField!
#IBOutlet weak var incomeAmountTextField: UITextField!
var income: Income?
override func viewDidLoad() {
super.viewDidLoad()
if let income = income {
incomeNameTextField.text = income.name
incomeAmountTextField.text = income.amount
}
updateSaveButtonState()
}
override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
super.prepare(for: segue, sender: sender)
guard segue.identifier == "saveIncomeUnwind" else { return }
let name = incomeNameTextField.text ?? ""
let amount = incomeAmountTextField.text ?? ""
income = Income(name: name, amount: amount)
}
func updateSaveButtonState() {
let nameText = incomeNameTextField.text ?? ""
let amountText = incomeAmountTextField.text ?? ""
saveButton.isEnabled = !nameText.isEmpty && !amountText.isEmpty
}
#IBAction func textEditingChanged(_ sender: UITextField) {
updateSaveButtonState()
}
}
this is the table view controller in which I want the new data to be presented.
import UIKit
class BudgetHomeTableViewController: UITableViewController {
var incomes: [Income] = []
var expenses: [Expense] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView(frame: CGRect.zero)
if let savedIncomes = Income.loadFromFile() {
incomes = savedIncomes
} else {
incomes = Income.loadSampleIncomes()
}
if let savedExpenses = Expense.loadFromFile() {
expenses = savedExpenses
} else {
expenses = Expense.loadSampleExpenses()
}
}
}
This is the cell where the data will be presented specifically
import UIKit
class BugetBalanceCell: UITableViewCell {
#IBOutlet weak var budgetBalanceText: UILabel!
var incomes: [Income] = []
var expenses: [Expense] = []
override func awakeFromNib() {
super.awakeFromNib()
let incomeTotal = incomes.map({Double($0.amount) ?? 0}).reduce(0, +)
let expenseTotal = expenses.map({Double($0.amount) ?? 0}).reduce(0, +)
let balance = incomeTotal - expenseTotal
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
First define your income,expenses arrays and load data
var incomes: [Income] = []
var expenses: [Income] = []
if let savedIncomes = Income.loadFromFile() {
incomes = savedIncomes
} else {
incomes = Income.loadSampleIncomes()
}
//do the same thing for load data to expenses array
you can get your balance = incomes - expenses using
let incomeTotal = incomes.map({Double($0.amount) ?? 0}).reduce(0, +)
let expenseTotal = expenses.map({Double($0.amount) ?? 0}).reduce(0, +)
let balance = incomeTotal - expenseTotal
use this value where you want to show in next Table View conntroller
(income as NSArray).valueForKeyPath("#sum.self")

How do I get the document id by clicking the button on the tableview cell?

I am using a xib file apart from the main storyboard in my view controller for displaying a post item, and there is comment button, upon being clicked it should go to another page where the list of comments related to that post is available. for that I need to pass the documentId of the post as well so that the accurate segue operation could be performed.
I have tried my things by searching google but till now nothing had worked for me.
if any more details are required please let me know
HomeViewController Swift Class
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView:UITableView!
var posts = [Post]()
var db: Firestore!
var postKey:String = ""
private var documents: [DocumentSnapshot] = []
//public var posts: [Post] = []
private var listener : ListenerRegistration!
var detailView: Post?
override func viewDidLoad() {
super.viewDidLoad()
db = Firestore.firestore()
self.navigationController?.navigationBar.isTranslucent = false
tableView = UITableView(frame: view.bounds, style: .plain)
let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "postCell")
tableView.backgroundColor = UIColor(white: 0.90,alpha:1.0)
view.addSubview(tableView)
var layoutGuide:UILayoutGuide!
if #available(iOS 11.0, *) {
layoutGuide = view.safeAreaLayoutGuide
} else {
// Fallback on earlier versions
layoutGuide = view.layoutMarginsGuide
}
tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
retrieveAllPosts()
//checkForUpdates()
postKey = detailView!._documentId
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
cell.set(post: posts[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let post = self.posts[indexPath.row]
performSegue(withIdentifier: "toCommentsList", sender: indexPath)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//segue.forward(posts, to: segue.destination)
guard let details = segue.destination as? CommentListViewController,
let index = tableView.indexPathForSelectedRow?.row
else {
return
}
// details.detailView = posts[index]
}
//I tried to connect this action to the button in the XIB file but not able to do so.
#IBAction func toCommentsSection(_ sender: Any) {
print(postKey + "hello")
// let postId11 = detailView?._documentId
performSegue(withIdentifier: "toCommentsList", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var vc = segue.destination as! CommentListViewController
vc.postId = postKey
}
}
PostViewCell Class
class PostTableViewCell: UITableViewCell {
#IBOutlet weak var usernameLabel: UILabel!
#IBOutlet weak var profileImageView: UIImageView!
#IBOutlet weak var subtitleLabel: UILabel!
#IBOutlet weak var postTextLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
// profileImageView.layer.cornerRadius = profileImageView.bounds.height / 2
// profileImageView.clipsToBounds = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func set(post:Post) {
if let userprofileImagUrl = post._postuserprofileImagUrl,
let imageUrl = URL(string: userprofileImagUrl) {
ImageService.getImage(withURL: imageUrl) { image in
self.profileImageView.image = image
}
}
usernameLabel.text = post._username
postTextLabel.text = post._postContent
subtitleLabel.text = post._postcategory
}
}
In PostTableViewCell create outlet of comment buttons
class PostTableViewCell: UITableViewCell {
#IBOutlet weak var btnComment: UIButton!
now in cellForRowAtIndex do add following line too
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
cell.btnComment.tag = indexPath.row
cell.btnComment.addTarget(self, action: #selector(self. toCommentsSection(sender:)) , for: .touchUpInside)
cell.set(post: posts[indexPath.row])
return cell
}
and in
#IBAction func toCommentsSection(_ sender: Any) {
let commentbutton = sender as! UIButton
let post = posts[commentbutton.tag]
postKey = post.postKey // or what key value it is
print(postKey + "hello")
// let postId11 = detailView?._documentId
performSegue(withIdentifier: "toCommentsList", sender: self)
}

Swift: Show data from tableView to another ViewController (JSON, Alamorife, AlamofireImage)

I'm trying to do an app in which the data were obtained from JSON.
In the picture below you can see the project:
Project
If we click on the photo opens the details page. The problem is because I do not know how to pick up the data shown in the details page. Please help me.
Here is the code
import UIKit
import Alamofire
import AlamofireImage
import SwiftyJSON
class ViewController: UIViewController ,UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate {
#IBOutlet weak var searchbarValue: UISearchBar!
weak open var delegate: UISearchBarDelegate?
#IBOutlet weak var tableView: UITableView!
var albumArray = [AnyObject]()
var url = ("https://jsonplaceholder.typicode.com/photos")
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.searchbarValue?.delegate = self
Alamofire.request("https://jsonplaceholder.typicode.com/photos").responseJSON { (responseData) -> Void in
if((responseData.result.value) != nil) {
let swiftyJsonVar = JSON(responseData.result.value!)
if let resData = swiftyJsonVar[].arrayObject {
self.albumArray = resData as [AnyObject]; ()
}
if self.albumArray.count > 0 {
self.tableView.reloadData()
}
}
}
}
public func searchBarTextDidEndEditing(_ searchBar: UISearchBar) // called when text ends editing
{
callAlamo(searchTerm: searchbarValue.text!)
}
func callAlamo(searchTerm: String)
{
Alamofire.request("https://jsonplaceholder.typicode.com/photos").responseJSON { (responseData) -> Void in
if((responseData.result.value) != nil) {
let swiftyJsonVar = JSON(responseData.result.value!)
if let resData = swiftyJsonVar[].arrayObject {
self.albumArray = resData as [AnyObject]; ()
}
if self.albumArray.count > 0 {
self.tableView.reloadData()
}
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return albumArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CostumTableViewCell
let title = albumArray[indexPath.row]
cell?.titleLabel?.text = title["title"] as? String
//cell?.url?.image = UIImage(data: title as! Data)
let imageUrl = title["thumbnailUrl"] as? String
//print(imageUrl)
let urlRequest = URLRequest(url: URL(string: imageUrl!)!)
Alamofire.request(urlRequest).responseImage { response in
if let image = response.result.value {
// print("image downloaded: \(title["url"])")
cell?.url?.image = image
}
}
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showDetails", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let indexPath = self.tableView.indexPathForSelectedRow?.row
let vc = segue.destination as! DetailsViewController
//here should be the code
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Also you can see the DetailsViewController code:
import UIKit
class DetailsViewController: UIViewController {
var image2 = UIImage()
var title2 = String()
#IBOutlet var mainImageView: UIImageView!
#IBOutlet var songTitle: UILabel!
override func viewDidLoad() {
songTitle.text = title2
mainImageView.image = image2
}
}
You can easily pass value from tableview to detail view using the below code :
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let indexPath = self.tableView.indexPathForSelectedRow
let cell : CostumTableViewCell = self.tableView.cellForRow(at: indexPath!) as! CostumTableViewCell
let vc = segue.destination as! DetailsViewController
vc.image2 = cell.url.image!
vc.title2 = cell.titleLabel.text!
}
class ViewController: UIViewController ,UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate {
var customArr = [CustomElement]()
var arr = [Any]()
// In viewDidLoad , you can append element to customArr
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var image = customArr[indexpath.row].image
var title = customArr[indexpath.row].title
arr.append(image)
arr.append(title)
performSegue(withIdentifier: "showDetails", sender: arr)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let indexPath = self.tableView.indexPathForSelectedRow?.row
if segue.identifier = "showDetails" {
if let vc = segue.destination as! DetailsViewController {
vc.arr = sender
}
}
//here should be the code
}
}
class DetailsViewController: UIViewController {
var arr = [Any]()
}

Parse from TableVC to textView in other viewController swift

I am new in programming, and have problem. I am using parse for my array in tableview. When the row is selected i want to segue on another view controller to textView. The tableview works good but i can't get text to textView.
tableVC:
import UIKit
import Parse
class ThirdTableVC: UITableViewController {
#IBOutlet weak var refresherQuotes: UIRefreshControl!
#IBOutlet var quoteTable: UITableView!
var selectedQuote: PFObject?
var quoteItems = [PFObject]()
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func updateQuotesResults(_ sender: UIRefreshControl) {
fetchQuotesData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadQuoteTexts(selectedQuote: selectedQuote)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return quoteItems.count
}
func fetchQuotesData() {
let quotesQuery = PFQuery(className: "TotalTest")
quotesQuery.whereKey("Subcategory", equalTo: selectedQuote ?? nil)
quotesQuery.findObjectsInBackground { (objects, error) in
if let realCategoryObjects = objects {
self.quoteItems = realCategoryObjects
self.tableView.reloadData()
self.refresherQuotes.endRefreshing()
}
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let quoteCell = tableView.dequeueReusableCell(withIdentifier: "quoteCell", for: indexPath)
let quoteItem = quoteItems[indexPath.row]
let quoteUserTitle = quoteItem.object(forKey: "TextQuote") as? String
quoteCell.textLabel?.text = quoteUserTitle
return quoteCell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showQuoteDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let quoteobject = quoteItems[indexPath.row] as? NSDate
let quoteController = (segue.destination as! UINavigationController).topViewController as! DetailViewController
quoteController.detailItem = quoteobject
quoteController.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
quoteController.navigationItem.leftItemsSupplementBackButton = true
}
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Row tapped: \(indexPath.row)")
let selectedQuotes: PFObject = quoteItems[indexPath.row]
let FourthVC = self.storyboard?.instantiateViewController(withIdentifier: "FourthViewController") as! FourthViewController
FourthVC.fourthTextView.text = quoteItems[indexPath.row] as? String
self.navigationController?.pushViewController(FourthVC, animated: true)
}
func loadQuoteTexts(selectedQuote: PFObject!) {
let quoteQuery = PFQuery(className: "TotalQuote")
quoteQuery.whereKey("QuoteSubs", equalTo: selectedQuote ?? nil)
quoteQuery.includeKey("QuoteSubs")
quoteQuery.findObjectsInBackground { (result: [PFObject]?, error) in
if let searchQuoteResults = result {
self.quoteItems = searchQuoteResults
self.quoteTable.reloadData()
}
}
}
}
How can I change this?
viewController with textView:
import UIKit
import Parse
class FourthViewController: UIViewController {
var getQuote: PFObject?
#IBOutlet weak var fourthTextView: UITextView!
#IBOutlet weak var fourthLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
fourthLabel.text! = getQuote as! String
fourthTextView.text! = getQuote as! String
}
}
Please help me to passing texts
If you use pushViewController do it like that , in did selectRowAt
let MainStory: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let desVC = MainStory.instantiateViewController(withIdentifier: "FourthViewController") as! FourthViewController
and now pass your text
desVC.getText = "here goes your text u want to pass"
FourthViewController
set up your var
var getText = String()
so you can finally use
self.navigationController?.pushViewController(desVC, animated: true)
so it will pass all parameters you previous add with desVC.getSomething
in FourthViewController you just need to use getText.
The problem is that you are changing from a view to another with pushViewController, by doing that your prepareForSegue won't be executed.
On your didSelectRow you need to call performSegue(withIdentifier:sender:).
You can lookup this question for more information on how to do it.

Resources