What can I do to access this Table View within a View Controller? - ios

I have checked out the other posts but I'm not sure next steps here. Here's what I have currently. Do I need to add a tableView variable somewhere else? Connect something differently?
class LookbookPostViewController: UIViewController {
#IBOutlet weak var titleLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
titleLabel.text = postArray[myIndex].title
// Do any additional setup after loading the view.
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
#IBOutlet weak var tableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
return postArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postViewCell", for: indexPath) as! LookbookPostViewCell
cell.postLabel.text = postArray[indexPath.row].title
print(postArray)
return cell
}
/
}
I then have this set up for my connections, but can't seem to get the Table View to recognize any data I'm trying to output.
I also have `class LookbookPostViewCell: UITableViewCell {
#IBOutlet weak var postLabel: UILabel!
}
`

I was able to solve this by changing:
class LookbookPostViewController: UIViewController
to
class LookbookPostViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
and then right clicking and making the delegate and datasource, the View Controller, like in this photo here.

Related

Not work UITableView in cellForRowAt But numberOfRowsInsection Work in Swift

I wrote a function to add a Cell in a UITableView.
numberOfRowsInSection works but cellForRowAt does not work.
class ShopMenuViewCell: UITableViewCell {
#IBOutlet weak var menuTableView: UITableView!
var menuPrice: MenuPrice!
override func awakeFromNib()
{
super.awakeFromNib()
}
}
extension ShopMenuViewCell
{
func setView()
{
self.menuTableView.delegate = self
self.menuTableView.dataSource = self
self.menuTableView.regCells(cells: ["ShopMenuInformationCell"])
DispatchQueue.main.async
{
self.menuTableView.reloadData()
}
}
}
extension ShopMenuViewCell : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "ShopMenuInformationCell", for: indexPath) as? ShopMenuInformationCell,
let menu = self.menuPrice,
let name = menu.name,
let price = menu.amt else { return ShopMenuInformationCell() }
return cell
}
}
In ShpMenuInformationCell.swift
class ShopMenuInformationCell: UITableViewCell
{
#IBOutlet weak var containerView: UIView!
#IBOutlet weak var shopNameLabel: UILabel!
#IBOutlet weak var menuNameLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
override func awakeFromNib()
{
super.awakeFromNib()
}
}
I saw the answer to add a ViewController, but I do not know what to do because it is not a storyboard. (.xib)
I think it is because I add UITableViewCell in the UITableViewCell class.
Do you know why?
I had a problem for about 5 days and found a solution!
First Reference Site: Joel's Answer cellForRowAtIndexPath: not called
Second reference site: Paolo's answer
Swift: UITableViewCell rowheight
When I add another kind of TableCell, the vertical size of the cell in question is small.
So I increased the size of the Cell's RowHeight (frame.height) before reloading the data and it's fixed!
Currently, cellforrowat runs safely. Your answers were helpful to the results.
Please try below code:
class ShopMenuViewCell: UITableViewCell
{
#IBOutlet weak var menuTableView: UITableView!
var menuPrice: MenuPrice!
override func awakeFromNib()
{
super.awakeFromNib()
}
fun setUpTable() {
self.menuTableView.regCells(cells: ["ShopMenuInformationCell"])
self.menuTableView.delegate = self
self.menuTableView.dataSource = self
self.menuTableView.reloadData()
}
}
and call the function setUpTable() from ShopMenuViewCell as an cell.setUpTable()
Try below code:
Solution 1
class ShopMenuViewCell: UITableViewCell {
#IBOutlet weak var menuTableView: UITableView! {
didSet {
self.menuTableView.regCells(cells: ["ShopMenuInformationCell"])
self.menuTableView.delegate = self
self.menuTableView.dataSource = self
}
}
}
Solution 2: Please check Anand Verma Answer

Can't pass data via segue

I make app with news feed which has to open on other ViewController. But can't pass data via segue.
Viewcontroller with newsfeed
class SecondViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var titlenews = ""
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "newsfeedCell", for: indexPath) as! NewsFeedCell
cell.newsfeed_title.text = self.news?[indexPath.item].headline
cell.newsfeed_topic.text = self.news?[indexPath.item].topic
cell.newsfeed_time.text = timetime(from: (self.news?[indexPath.item].time)!)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("tableview")
let vc = storyboard?.instantiateViewController(withIdentifier: "newsBody") as? NewsBody
vc?.labeltext = (self.news?[indexPath.item].headline)!
print((self.news?[indexPath.item].headline)!)
self.navigationController?.pushViewController(vc!, animated: true)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.news!.count
} //number of rows
#IBOutlet weak var tableview: UITableView!
var news: [Newsfeed]? = []
override func viewDidLoad() {
super.viewDidLoad()
getJSON()
}
func getJSON(){
///Here all do right
}
}
Viewcontroller which has to receive data from news feed
class NewsBody: UIViewController {
#IBOutlet weak var testLabel: UILabel!
var labeltext = ""
override func viewDidLoad() {
super.viewDidLoad()
print(labeltext)
testLabel.text = labeltext
}
}
print(labeltext) shows that NewsBody receive empty value or nothing.
But print((self.news?[indexPath.item].headline)!) inside of SecondViewController shows that I try to push proper value.
What I do incorrect between this actions? What wrong with segue and pass of data?
It seems that instantiateViewController(withIdentifier: "newsBody") triggers view load under the hood. It should not (in theory) but it might do just that in your case.
This means that viewDidLoad() will be called before the vc?.labeltext = (self.news?[indexPath.item].headline)! is executed.
I'd recommend you to do the following.
class NewsBody: UIViewController {
#IBOutlet weak var testLabel: UILabel!
var labeltext: String? {
didSet { updateUI() }
}
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
}
private func updateUI() {
testLabel.text = labeltext
}
}
This way if you set the labeltext property after the view is loaded, it will still trigger the UI update. And if you set the labeltext property before the view is loaded, as soon as viewDidLoad() is called.
BTW, you are not using segues here. But even if you do, you can easily use the same method as I proposed, because it allows you to stop thinking about whether property updates will update the UI.
Also please note that I made the property optional. It will allow you to avoid force casts and just do
vc?.labeltext = self.news?[indexPath.item].headline
UILabel.text is also an optional String property, so they will play well together.

Datepicker won't display in custom UITableViewCell class

I try to keep a separate custom cell class, but somehow the datepicker I dragged into it from storyboard refuses to show up after I ran it.
import UIKit
class eventViewController: UIViewController,UITextViewDelegate,UIScrollViewDelegate,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var timeTableView: UITableView!
#IBOutlet weak var eventText: UITextView!
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.eventText.delegate = self
self.scrollView.delegate = self
self.timeTableView.delegate = self
self.timeTableView.dataSource = self
self.timeTableView.register(startDateCell.self, forCellReuseIdentifier: "startDateCell")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "startDateCell", for: indexPath) as! startDateCell
//cell.startDatePicker.date = Date()
//cell.text = "anything"
return cell
}
}
class startDateCell: UITableViewCell {
#IBOutlet weak var startDatePicker: UIDatePicker!
}
I have the outlet connected to my datePicker in the custom cell and I also defined my custom cell class to be startDateCell in inspector, and I registered my custom cell in my view controller. It will throw a runtime error saying the datepicker is nil.
Can somebody explain why it isn't showing up?
Can you remove the following code from viewDidLoad() and ensure you have set reuse identifier of custom tableviewcell as "startDateCell" in storyboard and try again?
self.timeTableView.register(startDateCell.self,
forCellReuseIdentifier: "startDateCell")

How to modify the properties of only one custom cell of a table view?

I want to have a table view cell that contains a button that increments a label by 1 everytime that button is pressed. So if the button is pressed, the label displays: "1,2,3,4", etc. And I want each cell row to be independent from each other, meaning I only want the increment button in cell row 3 to modify the label of cell row 3 and same for cell row 4 and so on.
However my current code functionality does the following:
When I press the increment button it changes the label for all cells not just the label the button is pressed in (I don't want this).
When I scroll the table view all the labels change even when I haven't pressed the button in that row (I want don't want this either, I only want the label to change if its corresponding increment button has been pressed).
Can anyone help get my code or help me construct some code to help me achieve my goals?
Thanks in advance all help is highly appreciated!
My code:
import UIKit
var bookieFlavors = ["Chocolate Chip", "Sugar w/o icing", "Sugar w/ icing", "Peanut Butter", "Honey", "Shortbread", "Ginger", "Double Chocolate", "Macadamie Nut", "Oatmeal Raisin", "Snickerdoodle"]
var labelAmount = Int()
class FlavorsController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var flavorTable: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return bookieFlavors.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! FlavorTableCell
//flavor label configuration
cell.flavorLabel.text = bookieFlavors[indexPath.row]
//amount configuration
cell.bookieAmount.text = "= \(amount)"
return cell
class FlavorTableCell: UITableViewCell {
#IBOutlet weak var flavorLabel: UILabel!
#IBOutlet weak var bookieButton: UIButton!
#IBAction func bookieButton(_ sender: UIButton) {
for _ in 1...15 {
bookieAmount.text = "= \(String(describing: amount))"
}
labelAmount += 1
}
#IBOutlet weak var bookieAmount: UILabel!
You can not add button action in the tableview cell to do this. Please check below code for the solution.
import UIKit
class FlavorsController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var bookieFlavors = ["Chocolate Chip", "Sugar w/o icing", "Sugar w/ icing", "Peanut Butter", "Honey", "Shortbread", "Ginger", "Double Chocolate", "Macadamie Nut", "Oatmeal Raisin", "Snickerdoodle"]
var labelAmount = [Int]() // To keep track of the amount in each cell
#IBOutlet weak var flavorTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
for item in self.bookieFlavors {
self.labelAmount.append(0) //Initialise with default value
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return bookieFlavors.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! FlavorTableCell
//flavor label configuration
cell.flavorLabel.text = bookieFlavors[indexPath.row]
//amount configuration
cell.bookieAmount.text = "= \(self.labelAmount[indexPath.row])"
cell.bookieButton.tag = indexPath.row
cell.bookieButton.addTarget(self, action: #selector(bookieButton(_:)), for: .touchUpInside)
return cell
}
//To configure the button click and according changes
#IBAction func bookieButton(_ sender: UIButton) {
self.labelAmount[sender.tag] = self.labelAmount[sender.tag] + 1
let cell = self.flavorTable.cellForRow(at: IndexPath(row: sender.tag, section: 0)) as? FlavorTableCell
cell?.bookieAmount.text = "= \(self.labelAmount[sender.tag])"
}
}
class FlavorTableCell: UITableViewCell {
#IBOutlet weak var flavorLabel: UILabel!
#IBOutlet weak var bookieButton: UIButton!
#IBOutlet weak var bookieAmount: UILabel!
}

Custom Cell Labels in UITableView Does Not Populate

On my storyboard is a Tab Bar Controller with two view controllers. The first view controller has a UITableView, and the second view controller is used to collect data which will be displayed in table view format on the first view controller.
For this, I have created four swift files:
TARISKTREATMENT.swift - contains the class TARISKTREATMENT that's linked to the first view controller (the one with the UITableView)
TAADDRISKTREATMENT.swift - contains the class TAADDRISKTREATMENT that's linked to the second view controller.
TREATMENTS.swift - Struct that's used to collect data entered on second view controller.
CUSTOMTREATMENTCELL.swift - UITableViewCell class for the custom cell.
The second view controller collects the data from the user perfectly, and when I run print commands, I can see that the data is actually in the struct.
For some reason, the code from TARISKTREATMENT.swift does not populate the custom cell.
What am I doing wrong here?
CODE: TARISKTREATMENT.swift (View controller 1 with UITableView - the one that's not working...)
import UIKit
class TARISKTREATMENT: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var TreatmentsTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
TreatmentsTableView.dataSource = self
TreatmentsTableView.delegate = self
TreatmentsTableView.reloadData()
}//END - viewDidLoad
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TreatmentsManager.newTreatments.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let IndividualCell = TreatmentsTableView.dequeueReusableCellWithIdentifier("TreatmentCell", forIndexPath: indexPath) as! CUSTOMTREATMENTCELL
IndividualCell.outletLabel_TreatmentPackageName.text = TreatmentsManager.newTreatments[indexPath.row].varTreatmentPackageName
IndividualCell.outletLabel_TreatmentDescription.text = TreatmentsManager.newTreatments[indexPath.row].varTreatmentPackageDetail
IndividualCell.outletLabel_TreatmentResponsiblePerson.text = TreatmentsManager.newTreatments[indexPath.row].varTreatmentResponsiblePerson
IndividualCell.outletLabel_TreatmentDTGCompleted.text = String(TreatmentsManager.newTreatments[indexPath.row].varTreatmentDTGCompleted)
let varSelectPriorityPic = TreatmentsManager.newTreatments[indexPath.row].varTreatmentPriority
switch varSelectPriorityPic {
case "HIGH":
IndividualCell.outletImage_TreatmentPriority.image = imageTreatmentPriorityHigh
case "MEDIUM":
IndividualCell.outletImage_TreatmentPriority.image = imageTreatmentPriorityMedium
case "LOW":
IndividualCell.outletImage_TreatmentPriority.image = imageTreatmentPriorityLow
default:
break
}
return IndividualCell
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath){
if (editingStyle == UITableViewCellEditingStyle.Delete){
TreatmentsManager.newTreatments.removeAtIndex(indexPath.row)
TreatmentsTableView.reloadData()
}
}
}
CODE: TREATMENTS.swift
import UIKit
var TreatmentsManager: classTreatmentsManager = classTreatmentsManager()
struct structTreatment {
var varTreatmentPackageName : String
var varTreatmentPackageDetail : String
var varTreatmentResponsiblePerson : String
var varTreatmentPriority : String
var varTreatmentDTGCompleted : NSDate
}
class classTreatmentsManager: NSObject {
var newTreatments = [structTreatment]()
func funcAddTreatment(varTreatmentPackageName: String, varTreatmentPackageDetail: String, varTreatmentResponsiblePerson: String, varTreatmentPriority: String, varTreatmentDTGCompleted: NSDate){
newTreatments.append(structTreatment(varTreatmentPackageName: varTreatmentPackageName, varTreatmentPackageDetail: varTreatmentPackageDetail, varTreatmentResponsiblePerson: varTreatmentResponsiblePerson, varTreatmentPriority: varTreatmentPriority, varTreatmentDTGCompleted: varTreatmentDTGCompleted))
}
}
CODE: CUSTOMTREATMENTCELL.swift
import UIKit
class CUSTOMTREATMENTCELL: UITableViewCell {
#IBOutlet weak var outletImage_TreatmentPriority: UIImageView!
#IBOutlet weak var outletLabel_TreatmentPackageName: UILabel!
#IBOutlet weak var outletLabel_TreatmentDescription: UILabel!
#IBOutlet weak var outletLabel_TreatmentResponsiblePerson: UILabel!
#IBOutlet weak var outletLabel_TreatmentDTGCompleted: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
I've uploaded a small video to show what's (not) happening here.
Your assistance is appreciated - thanks!
Everything is fine in your code. What you miss is reloading the data :
override func viewWillAppear() {
super.viewWillAppear()
TreatmentsTableView.reloadData()
}

Resources