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 { }
Related
I have some static cells and this don't want to change their size by overweight content in label. I have all constraints(top, bottom, leading,tralling) in each cells, also I have this code:
import UIKit
class FilmTableViewController: UITableViewController {
#IBOutlet weak var posterView: UIImageView!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var yearLabel: UILabel!
#IBOutlet weak var directorLabel: UILabel!
#IBOutlet weak var actorsLabel: UILabel!
#IBOutlet weak var countryLabel: UILabel!
#IBOutlet weak var plotLabel: UILabel!
#IBOutlet weak var RatingLabel: UILabel!
private let networkingService = NetworkingService()
var filmImbdbID = ""
override func viewDidLoad() {
super.viewDidLoad()
loadFilm(filmImbdbID)
}
override func viewDidAppear(_ animated: Bool) {
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 80
}
private func loadFilm(_ film: String) {
networkingService.fetchFilmRecording(matching: film) { [weak self] response in
guard let `self` = self else {
return
}
self.directorLabel.text = response.recordings?.director
self.titleLabel.text = response.recordings?.title
self.yearLabel.text = response.recordings?.year
self.actorsLabel.text = response.recordings?.actors
self.countryLabel.text = response.recordings?.country
self.plotLabel.text = response.recordings?.plot
self.RatingLabel.text = response.recordings?.rating
if let imageUrl = URL(string: response.recordings!.poster) {
guard let data = try? Data(contentsOf: imageUrl) else { return }
let image = UIImage(data: data)
self.posterView.image = image
}
}
}
}
Also numberOfLines is 0.
When I see this view, it don't work, however if I slide down it looks like this:
Please, some idea to fix it? :(
You need to update your code, cause is not clear what's happening.
Anyway you should use or:
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 80
or delegate methods
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableView.automaticDimension
}
not both
I'm adding a new TableVIewto the project and I'm also creating a custom class fro the cell. I'm doing as usual : New file/ Cocoa Touch Class / UITableViewCell / name. As soon as I start adding properties I get the error dough properties are declared as!. It doesn't happen on my other custom cell class. Can you see what am I doing wrong with this new class?
No error on this class :
import UIKit
class CalendarTableViewCell: UITableViewCell {
#IBOutlet weak var dayLabel: UILabel!
var cellId: String!
var cellWeekday: Int!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func prepareForReuse() {
super.prepareForReuse()
// Set your default background color, title color etc
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
and the new class that makes xCode complain:
import UIKit
class ProductTableViewCell: UITableViewCell {
#IBOutlet weak var productImageView: UIImageView!
#IBOutlet weak var productIDLabel: UILabel!
#IBOutlet weak var productIDInfoLabel: UILabel!
#IBOutlet weak var categoryLabel: UILabel!
#IBOutlet weak var categoryInfoLabel: UILabel!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var nameInfoLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
#IBOutlet weak var priceInfoLabel: UILabel!
#IBOutlet weak var quantityLabel: UILabel!
#IBOutlet weak var quantityInfoLabel: UILabel!
var productImage: UIImage!
var category: String!
var productId: String!
var name: String!
var price: String
var vendor: String!
var cellId: Int64
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
}
}
It's something I overlooked for sure but I can't spot it.
What should I check?
Your var cellId: Int64 is not initialized. In first cell you explicitly specified that you will initialize it before use with exclamation mark, but not in the second cell.
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
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")
}
}
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