Custom TableViews + CustomCell - swift

This is probably a newbie mistake and question but what's wrong with this code below?
class CustomCell: UITableViewCell {
#IBOutlet weak var TitleLabel: UILabel!
#IBOutlet weak var ImageView: UIImageView!
#IBOutlet weak var NumbersView: 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
}
func customInit(text: String, numbersText: String, photo: UIImage) {
self.TitleLabel.text = text
self.NumbersView.text = text
self.ImageView.photo = UIImage)
}
}
I'm following a tutorial called " SegmentedControl - Switch 'Custom' TableViews: Swift 3" and the user used the following code: func customInit(text: String, accessoryText: String but I changed it to include an UIImage but I don't know if thats correct or needed.

It should be like this:
self.ImageView.image = photo
self.NumbersView.text = numbersText

Related

How to localize tableView in Swift?

I'm translating my app to multiple languages, storyboard translations are working perfectly, but I'm struggling to localize the content of tableView (tableView cell) and corresponding viewController.
I have created string file Localizable.strings for 2 languages so far.
FirstViewController contains an array with names which is passed to TableViewCell as UILabel and later to corresponding DetailViewController.
TableViewCell:
class UpperTableViewCell: UITableViewCell {
#IBOutlet weak var upperImage: UIImageView!
#IBOutlet weak var upperBodyType: UILabel!
#IBOutlet weak var upperLblName: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
The objectID reference in Main.strings of the name label is
"BkN-Wi-Ai3.text" = "Label1";
However I can't figure out how to translate and parse the translated data of the name array and bodyType array into labels in TableView.
Thank you for suggestions.
Try with the following steps:
Make String extension (Tablename should be your .strings file):
extension String {
 
    func localized(bundle: Bundle = .main, tableName: String = "Localized”) -> String {
        return NSLocalizedString(self, tableName: tableName, value: "**\(self)**", comment: "")
    }
}
After that update your awakeFromNib:
override func awakeFromNib() {
super.awakeFromNib()
upperBodyType.text = upperBodyType.text?.localized()
upperLblName.text = upperLblName.text?.localized()
}

How to update UITableView when a CustomCell label value changes?

I have a custom cell class with two buttons and one label defined in its own class. Am using protocol-delegates to update the value of the label when the button is pressed. But am not able to figure out how to update the UITableView.
protocol customCellDelegate: class {
func didTapDecrementBtn(_ sender: AllCountersTableViewCell)
func didTapIncrementBtn(_ sender: AllCountersTableViewCell)
func updateTableViewCell(_ sender: AllCountersTableViewCell)
}
class AllCountersTableViewCell: UITableViewCell {
#IBOutlet weak var counterValueLbl: UILabel!
#IBOutlet weak var counterNameLbl: UILabel!
#IBOutlet weak var counterResetDateLbl: UILabel!
#IBOutlet weak var counterDecrementBtn: UIButton!
#IBOutlet weak var counterIncrementBtn: UIButton!
weak var delegate: customCellDelegate?
#IBAction func decrementBtnPressed(_ sender: UIButton) {
delegate?.didTapDecrementBtn(self)
delegate?.updateTableViewCell(self)
}
#IBAction func incrementBtnPressed(_ sender: UIButton) {
delegate?.didTapIncrementBtn(self)
delegate?.updateTableViewCell(self)
}
In my ViewController, I have provided the delegate. But reloadData() is not working, so although sender.counterLbl.value is changing its not reflecting on the view.
extension AllCountersVC: customCellDelegate {
func didTapIncrementBtn(_ sender: AllCountersTableViewCell) {
guard let tappedCellIndexPath = tableView.indexPath(for: sender) else {return}
let rowNoOfCustomCell = tappedCellIndexPath[1]
let newValue = String(allCounter[rowNoOfCustomCell].incrementCounterValue(by: allCounter[rowNoOfCustomCell].counterIncrementValue))
sender.counterValueLbl.text = newValue
}
func updateTableViewCell(_ sender: AllCountersTableViewCell) {
allCountersTableView.reloadData()
}
In cellForRow you must set cell.delegate = self for this logic to start working. Its not enough just to make you controller confroms to your custom cell delegate protocol. From your post I assume delegate is always nil in the cell, that is why it does not work.

How can I create a protocol for a UITableViewCell?

I have a few UITableViewCell's that have a few different layouts depending on if they're teammates, enemies, etc. But I have to treat each type differently etc. So I tried to cut down on replicated code by using a protocol,
I've created a protocol for a UITableViewCell like so:
protocol ViewCellProtocol {
var teamRank: UILabel! { get set }
var ranking: UILabel! { get set }
var rankDelta: UILabel! { get set }
var upDownIndicator: UILabel! { get set }
var textLabel : UILabel? { get }
}
This is my class:
import UIKit
class TeamStatsTableViewCell: UITableViewCell {
#IBOutlet weak var teamRank: UILabel!
#IBOutlet weak var ranking: UILabel!
#IBOutlet weak var rankDelta: UILabel!
#IBOutlet weak var upDownIndicator: 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
}
}
Then when I try to use it
func playerViewCell(_ tableView: UITableView, indexPath: IndexPath) -> ViewCellProtocol {
let cell = tableView.dequeueReusableCell(withIdentifier: "teamNameCell")! as! TeamStatsTableViewCell
let rank = sections[indexPath.section].data[indexPath.row]["rank"] as? Int
let (rating, ratingDelta) = selectRating(section: indexPath.section, row: indexPath.row)
let indicator = decideRatingIndicator(ratingDelta: ratingDelta, cell: cell)
cell.upDownIndicator?.text = "\(indicator)"
cell.teamRank?.text = "#\(rank!)"
cell.ranking?.text = String(rating)
cell.rankDelta.text = String(format: "%.0f", ratingDelta)
cell.textLabel?.text = sections[indexPath.section].data[indexPath.row]["username"] as? String
return cell as! ViewCellProtocol
}
I get an error:
Could not cast value of type '.TeamStatsTableViewCell' (0x1008d35d8) to '.ViewCellProtocol' (0x10ea37db8).
2018-04-24 22:00:27.137516-0600[434:72294] Could not cast value of type '.TeamStatsTableViewCell' (0x1008d35d8) to '.ViewCellProtocol' (0x10ea37db8).
I wish it would tell me what part it doesn't conform to. Any suggestions? Fairly new to swift kind of looking at protocols like interface{} in Go. Thanks.
Your custom cell class might be implementing all the stuff that's in the protocol, and that'd be enough in objC perhaps, but here you must declare that you implement that protocol explicitly
class TeamStatsTableViewCell: UITableViewCell, ViewCellProtocol {
#IBOutlet weak var teamRank: UILabel!
#IBOutlet weak var ranking: UILabel!
#IBOutlet weak var rankDelta: UILabel!
#IBOutlet weak var upDownIndicator: 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
}
}
You need to declare that TeamStatsTableViewCell conforms to ViewCellProtocol, for example by adding this extension:
extension TeamStatsTableViewCell: ViewCellProtocol { }

How to use UIButtons in a Cell with Functions?

I created a custom cell added the actions and outlets.
I want to be able to get the cell indexpath when the cell button is pressed.
I am send data to my parse server and I need to the cell indexPath.row so when someone clicks the button the count for likes or dislikes goes up.
My Custom Cell :
class myTVC: UITableViewCell {
#IBOutlet weak var greenUp: UIButton!
#IBOutlet weak var redDown: UIButton!
#IBOutlet weak var imageViewTVC: UIImageView!
#IBOutlet weak var upVote: UILabel!
#IBOutlet weak var downVote: UILabel!
#IBOutlet weak var saveButton: UIButton!
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
}
#IBAction func voteDownPressed(sender: UIButton) {
print("downVote")
}
#IBAction func voteUpPressed(sender: UIButton) {
print("upVote")
}
}

UITextfield value for each indexpath.row

My uitableview consists of 10 cells and each cell has 2 uitextfield's.
I need to take values from each uitextfield in each cell and add it to an array
// my custom cell
class MatchTableViewCell: UITableViewCell, UITextFieldDelegate {
#IBOutlet weak var Team2Score: UITextField!
#IBOutlet weak var Team1Score: UITextField!
#IBOutlet weak var Team2: UILabel!
#IBOutlet weak var Image2: UIImageView!
#IBOutlet weak var Image1: UIImageView!
#IBOutlet weak var Team1: 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
}
}
Make sure in the cell initializer for tableviewcontroller that your using your custom cell name and that you've set your identifier correctly. Then just initalize a cell and say something to the effect of
cell.Team2Score.text = "100"
you will need a global array to hold the strings. So..
var wordArray: [String] = []
you will need to add a button within the cell so when you hit the button it will add (append in the input of string (letters) to the array.
You need to add a tag to the button to know which cell it was clicked in.
button.tag = indexPath.row
#IBaction button(sender: UIButton){
var team2Words = Team2Score.text
wordArray.append(team2Words)
// do the samething for Team1Score
// you can use and if statement to check if one or the other one is empty
}
This will give you a lead