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

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.

Related

Reassign TableView Cell Variable from another ViewController

I'm working on an App where you can track your reading Progress for Books. I have 3 ViewControllers. One is the HomeViewController, where I have a TableView which displays the book. Second is the AddBookController, where you can enter some data, press a Button and create a new row in the TableView. Third is the BookDetailViewController, which is showing when you click on the selected row. Here I am stuck. There is a button you press and the corresponding TableView Cell should update its page number.
Can I use Notification Center for this? There is no Segue from HomeViewController to BookDetailViewController.
HomeViewController
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SendingBookDataProtocol {
#IBOutlet weak var addBookButton: UIButton!
#IBOutlet var tableView: UITableView!
var items = [BookItem]()
override func viewDidLoad() {
super.viewDidLoad()
tableView?.delegate = self
tableView?.dataSource = self
let nib = UINib(nibName: "BookCell", bundle: nil)
tableView?.register(nib, forCellReuseIdentifier: "BookCell")
}
func sendDataToHomeController(bookEntry item:BookItem) {
items.append(item)
tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
items.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let bookDetailVc = self.storyboard?.instantiateViewController(withIdentifier: "BookDetailView") as? BookDetailViewController
let item = items[indexPath.row]
let currentPageInt = Float(item.currentPage)!
let totalPagesInt = Float(item.totalPages)!
bookDetailVc?.lblName = item.title
bookDetailVc?.lblCurrentPage = item.currentPage
bookDetailVc?.lblTotalPages = item.totalPages
self.navigationController?.pushViewController(bookDetailVc!, animated: true)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "BookCell", for: indexPath) as! BookCell
let item = items[indexPath.row]
cell.bookImage.image = item.image
cell.title.text = item.title
cell.author.text = item.author
cell.pageNumbers.text = "P. " + item.currentPage + " / " + item.totalPages
cell.title.text = item.title
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "getBookData" {
let addBookVC: AddBookController = segue.destination as! AddBookController
addBookVC.delegate = self
}
}
}
BookDetailView
class BookDetailViewController: HomeViewController{
#IBOutlet weak var bookTitle: UILabel!
#IBOutlet weak var currentPageDetail: UILabel!
#IBOutlet weak var totalPagesDetail: UILabel!
var lblName = String()
var lblCurrentPage = String()
var lblTotalPages = String()
override func viewDidLoad() {
super.viewDidLoad()
bookTitle.text = lblName
currentPageDetail.text = lblCurrentPage
totalPagesDetail.text = lblTotalPages
}
}
your self.navigationController? is null?
try it
self.present(bookDetailVc!, animated: true)
I hope this helps you.

How to pass data with delegate from footer cell to view controller?

Ive been stuck trying to pass data from the FoodEatenController(FEC) Footer to the TotalCaloriesController. The code that I have now it shows NOTHING in the calorieLbl of the TotalCalorieController(TCC).
The delegate that ive been using to pass the data from the FEC to the TCC does not pass the text/string data that is in the FoodFooter calorieTotallbl to the TEC calorieLbl
the data that populates the cells of the FEC is retrieved from Cloud Firestore and passed in from anotherView Controller (FoodPickerController)
import UIKit
class FoodEatenController: UIViewController{
var selectedFood: FoodList! // allows data to be passed into the VC
// allows data to be sepearted into sections
var foodItems: [FoodItem] = []
var groupedFoodItems: [String: [FoodItem]] = [:]
var dateSectionTitle: [String] = []
#IBOutlet weak var tableView: UITableView!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? TotalCalorieController {
}
}
}
extension FoodEatenController: UITableViewDelegate, UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return dateSectionTitle.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let date = dateSectionTitle[section]
return groupedFoodItems[date]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let foodCell = tableView.dequeueReusableCell(withIdentifier: "FoodCell") as! FoodCell
let date = dateSectionTitle[indexPath.section]
let foodItemsToDisplay = groupedFoodItems[date]![indexPath.row]
foodCell.configure(withCartItems: fooditemsToDisplay.foodList)
return foodCell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let foodHeader = tableView.dequeueReusableCell(withIdentifier: "FoodHeader") as! FoodHeader
let headerTitle = dateSectionTitle[section]
foodHeader.dateLbl.text = "Date: \(headerTitle)"
return foodHeader
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let foodFooter = tableView.dequeueReusableCell(withIdentifier: "FoodFooter") as! FoodFooter
let date = dateSectionTitle[section]
let arrAllItems = groupedFoodItems[date]!
var total: Float = 0
for item in arrAllItems {
let eaten = item.productList
let selectedMeal = item.foodList.selectedOption
if selectedMeal == 1 {
total = total + (Float(eaten!.calorie))
}
}
foodFooter.calorieTotal.text = String(subtotal!)
foodFooter.delegate = self
return foodFooter
}
}
extension FoodEatenController: EatenFoodDelegate {
func onTouchCaloireInfo(info: String) {
let popUp = self.storyboard?.instantiateViewController(withIdentifier: "AdditionalCostsVC") as! TotalCalorieController
popUp.calorieLbl.text = info
}
}
import UIKit
protocol EatenFoodDelegate: class {
func onTouchCaloireInfo(info: String)
}
class FoodFooter: UITableViewCell {
weak var delegate: EatenFoodDelegate? = nil
#IBOutlet weak var calorieTotal: UILabel!
#IBOutlet weak var totalInfoBtn: UIButton!
#IBAction func totalOnClicked(_ sender: AnyObject) {
self.delegate?. onTouchCaloireInfo(info: calorieTotal.text!)
}
}
class TotalCalorieController: UIViewController, EatenFoodDelegate {
func onTouchCaloireInfo(info: String) {
calorieLbl.text = info
}
#IBOutlet weak var calorieLbl: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func returnButton(_ sender: Any) {
dismiss(animated: true, completion: nil)
print("Close Taxes and Fees")
}
}
Add the following line at the end of the func onTouchCaloireInfo(info:)
self.present(popUp, animated: true, completion: nil)
If you would like to be sure that the function onTouchCaloireInfo(info:) gets called, just add the following line:
debugPrint("onTouchCaloireInfo")
And check, if it prints the given string in the console of the Xcode
extension FoodEatenController: EatenFoodDelegate {
func onTouchCaloireInfo(info: String) {
debugPrint("onTouchCaloireInfo")
let popUp = self.storyboard?.instantiateViewController(withIdentifier: "AdditionalCostsVC") as! TotalCalorieController
self.present(popUp, animated: true) {
popUp.calorieLbl.text = info
}
}
}

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)
}

Passing data with segue in the tableViewCell

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()
}

How to instantiate a new view controller programmatically

I have a ViewController with two UIButtons and UIlabels.
In order to make similar ViewController of this, I would like to instantiate a new view controller programmatically
like this.
let vc = storyboard.instantiateViewControllerWithIdentifier("Main")
Then navigate to the view controller like this:
navigationcontroller?.pushViewController(vc, animated: true)
I have set StoryBoard ID as "Main", however I do not know where I can write these codes.
class ViewController: UIViewController, AVAudioPlayerDelegate {
let url1 = Bundle.main.bundleURL.appendingPathComponent("music1.mp3")
let url2 = Bundle.main.bundleURL.appendingPathComponent("music2.mp3")
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var yourButton1: customButton!
#IBOutlet weak var yourButton2: customButton!
override func viewDidLoad() {
super.viewDidLoad()
label1.text = "Hello1"
label2.text = "Hello2"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func player(url: URL) {
do {
try player = AVAudioPlayer(contentsOf:url)
player.play()
} catch {
print(error)
}
}
#IBAction func pushButton1(sender: UIButton) {
player(url: url1)
}
#IBAction func pushButton2(sender: UIButton) {
player(url: url2)
}
}
tableView
class SecondTableViewController: UITableViewController {
var names = [String]()
var identities = [String]()
override func viewDidLoad() {
names = ["name1","name2","name3","name4"]
identities = ["Main","Main2","Main3","Main4"]
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
let label1 = cell?.viewWithTag(1) as! UILabel
label1.text = "\(names[indexPath.row])"
return cell!
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vcName = identities[indexPath.row]
let ViewController = storyboard?.instantiateViewController(withIdentifier: vcName)
self.navigationController?.pushViewController(ViewController!, animated: true)
}
}
You need to set Storyboard ID value for the view controller in storyboard and use it here:
let storyboard = UIStoryboard(name: "StoryboardName", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RegistrationController")
navigationcontroller?.pushViewController(vc, animated: true)
Edit:
var urls1 = [String]()
var urls2 = [String]()
override func viewDidLoad() {
names = ["name1","name2","name3","name4"]
identities = ["A","B","C","D"]
urls1 = ["url1","url2" ....]
urls2 = ["url1","url2" ....]
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let url1 = urls1[indexPath.row]
let url2 = urls2[indexPath.row]
//let ViewController = storyboard?.instantiateViewController(withIdentifier: vcName) this is wrong you only have one viewcontroller on storyboard and its storyboard id is fixed.
let viewController: ViewController = storyboard?.instantiateViewController(withIdentifier: "StoryboardID") as! ViewController
viewController.url1 = url1
viewController.url2 = url2
self.navigationController?.pushViewController(ViewController!, animated: true)
}

Resources