Setting imageView in cell - swift

i am new to Swift and I have seen tons of guides on the topic. However in my case, it's working. I have a custom cell file:
class FileCell: UITableViewCell {
#IBOutlet weak var firstName: UILabel!
#IBOutlet weak var cellImage: UIImageView!
func updateImage(name: String) {
cellImage.image = UIImage(named: name)
}}
In the view controller I am using "willDisplay" function as follows:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "FileCell") as! FileCell
let user = users[indexPath.row]
if user.email.isEmpty {
//cell.cellImage.image = UIImage(named: "folder.png")
cell.updateImage(name: "folder.png")
} else {
//cell.cellImage.image = UIImage(named: "file.png")
cell.updateImage(name: "file.png")
}
}
where i try to change imageView in cell depending on the data incoming to cell. However, the images either don't display at all or cells are not showing up.
Thanks in advance for tips on what i am doing wrong.

You should not dequeue a new cell, since you already have one.
Just skip the first statement:
// let cell = tableView.dequeueReusableCell(withIdentifier: "FileCell") as! FileCell
But one question: Why are you using the willDisplay delegate method? I would suggest to set up the cell in tableView(_:cellForRowAt:):
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "FileCell") as! FileCell
let user = users[indexPath.row]
cell.firstName.text = user.name // or something
if user.email.isEmpty {
cell.updateImage(name: "folder.png")
} else {
cell.updateImage(name: "file.png")
}
return cell
}

Related

My function tableView.didSelectRow is not working

I have a tableView with custom cells and my goal is to be able to click on one and print the number of the current row.
Right now when I click on a cell not happens and I can't understand why.
This is the code:
//MARK: - UITableDataSource
extension ChannelViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return groupResult.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let group = groupResult[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: K.cellContactNibName, for: indexPath) as! ContactCell
cell.usernameLabel.text = group.name
cell.messageLabel.text = group.recentMessage
let storage = Storage.storage()
let storageRef = storage.reference()
// Reference to an image file in Firebase Storage
let reference = storageRef.child("imagesFolder/\(group.image)")
// UIImageView in your ViewController
let imageView: UIImageView = cell.uImage
// Placeholder image
let placeholderImage = UIImage(named: "MeAvatar")
// Load the image using SDWebImage
imageView.sd_setImage(with: reference, placeholderImage: placeholderImage)
cell.uImage.image = imageView.image
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
}
}
and as you can see in the screen the single selection is enabled:
change to
extension ChannelViewController: UITableViewDataSource, UITableViewDelegate
or move the method into another extension conformed to UITableViewDelegate
also, remember to set the tableView's delegate to the ChannelViewController

Did select show check/image using custom tableview cell

Ok so this seems like a really simple question, but I can't seem to solve it efficiently or find anything on the web that has the correct answer. So here goes.
I have a tableViewController with a prototype cell running off a custom class. Inside the prototype cell I have an image of a checkmark which I want to display when the user selects the cell and hide the image when another cell gets selected. I've got an approach working but it requires me to reloadData on the table which seems really inefficient. So there must be a better way right?
My code...
//CUSTOM CLASS (trimmed code down to just show relevant code)
class GoalsTableViewCell: UITableViewCell {
#IBOutlet weak var gNameLabel: UILabel!
#IBOutlet weak var gIsSelectedImage: UIImageView!
}
}
//TABLE VIEW CONTROLLER (trimmed it down to just show relevant code)
class GoalsTableVC: UITableViewController {
var selectedGoalId = ""
var selectedInd = 0
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let gCell = tableView.dequeueReusableCell(withIdentifier: "gCell", for: indexPath) as! GoalsTableViewCell
gCell.gNameLabel.text = goalsData[indexPath.row].gName
if indexPath.row == selectedInd {
gCell.gIsSelectedImage.isHidden = false
} else {
gCell.gIsSelectedImage.isHidden = true
}
return gCell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedGoalId = goalsData[indexPath.row].id!
selectedInd = indexPath.row
tableView.reloadData()
}
}
It's possible to reload only the affected rows
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedGoalId = goalsData[indexPath.row].id!
let indexPathsToReload = [indexPath, IndexPath(row: selectedInd, section: 0)]
selectedInd = indexPath.row
tableView.reloadRows(at: indexPathsToReload, with: .automatic)
}

Swift How should Custom Cell load tableview data and make it expand when I use didSelectRowAt?

I create a custom cell that include tableview
Here's the MainTableView and data
var data = [People(name:"Kevin",age:"18",tall:"180")]
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainCell", for: indexPath) as! MainTableViewCell
cell.title = data[indexPath.row].name
cell.detail = ["age \(data[indexPath.row].age)","tall \(data[indexPath.row].tall)"]
cell.isExtend = false
return cell
}
I try to tap cell to expand tableView height and load data
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainCell", for: indexPath) as! MainTableViewCell
cell.isExpand = !cell.isExpand
}
Here's the MainTableViewCell
class MainTableViewCell: UITableViewCell {
#IBOutlet weak var title: UILabel!
#IBOutlet weak var detailTableView: UITableView!
#IBOutlet weak var detailTableViewHeight: NSLayoutConstraint!
var detail:[String] = []{
didSet{
detailTableView.reloadData()
}
}
var isExpand: Bool = false{
didSet{
detailTableView.isHidden = !isExpand
detailTableView.reloadData()
detailTableViewHeight.constant = isExpand ? detailTableView.contentSize.height:0
}
}
override func awakeFromNib() {
super.awakeFromNib()
detailTableView.delegate = self
detailTableView.dataSource = self
detailTableView.isScrollEnabled = false
detailTableViewHeight.constant = 0
}
}
I use tableView to load data and hide some of theme first, and tapped to show and hide theme
but It happened nothing
Did I forgot something?
In cellforRowAt:
let cell: MoreUserDetails = tableView.dequeueReusableCell(withIdentifier: "MoreUserDetails") as! MoreUserDetails
cell.backgroundColor = .clear
cell.selectionStyle = .none
if isExpand {
// your func when its expanded
}
else {
// your func when its hidden
}
return cell
in did select
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
if isSelected[indexPath.row] {
isExpand[indexPath.row] = false
}
else {
isExpand[indexPath.row] = true
}
self.tableVIew.reloadData()
}

Swift Show Overlapping Button on TableViewCell

I have a button in a TableViewCell the overlaps the welcome TableViewCell. It looks fine when the view loads, however when I scroll down the tableview and scroll back up the button is cut off by the next tableviewcell.
I found a hack to make the background clear for the message TableViewCell, however, the bottom of the button is still not clickable.
Is there a way to set the priority of the button to be on top of the next?
HomeTableViewController.swift
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "heroCell", for: indexPath) as! HeroTableViewCell
heroCell = cell
cell.separatorInset = UIEdgeInsets(top: 0, left: 10000, bottom: 0, right: 0)
return cell
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: "welcomeCell", for: indexPath) as! WelcomeTableViewCell
// Set Intro Name
if let user = Auth.auth().currentUser {
// User is signed in
// References to firebase
let userFS = Firestore.firestore().collection("users")
// Set the navigation title to users name
userFS.document(user.uid).getDocument { (document, error) in
if let userInfo = document {
let firstName = userInfo["firstName"] as! String
cell.introLabel.text = "Hey, \(firstName)"
} else {
print("User name does not exist")
}
}
}
return cell
case 2:
let cell = tableView.dequeueReusableCell(withIdentifier: "tripsCell", for: indexPath) as! TripTableViewCell
return cell
case 3:
let cell = tableView.dequeueReusableCell(withIdentifier: "suggestionsCell", for: indexPath) as! SuggestionTableViewCell
return cell
default:
let cell = tableView.dequeueReusableCell(withIdentifier: "popularsCell", for: indexPath) as! PopularTableViewCell
return cell
}
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath.section {
case 0: return 425
case 1: return 200
case 2: return 400
case 3: return 400
default: return 400
}
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 425
}
HeroTableViewCell.swift
class HeroTableViewCell: UITableViewCell {
// MARK: - Outlets
#IBOutlet weak var heroImage: UIImageView!
#IBOutlet weak var heroImageViewTopConstraint: NSLayoutConstraint!
#IBOutlet weak var planTripButton: SpringButton!
// MARK: - Variables
let notification = UINotificationFeedbackGenerator()
override func awakeFromNib() {
}
// MARK: - Actions
#IBAction func addTripButtonPressed(_ sender: UIButton) {
planTripButton.animation = "pop"
planTripButton.animate()
notification.notificationOccurred(.success)
}
}
If I understand your question correctly, you want + button to hover over the UITableView, so that it is clickable regardless of which cell the user has scrolled to?
In the image below, I have place my action button (the pencil in the top right of the view) at the same level in the view hierarchy as my tableView. So as the user scrolls, that button is always visible and the user can click at any time.
Please note where the Action Button sits relative to the tableView in the Document outline. It is at the same level. It is not a subview of the tableView.

Initialize optional UIActivityIndicatorView in Swift

I have no idea what I am doing wrong. In my TableViewController, I want each cell to have a UIActivityIndicator when tapped. So in my TableViewCell class I have the following:
#IBOutlet weak var loadingIcon: UIActivityIndicatorView!
And in TableViewController I have the following:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "taskCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? TodayTableViewCell else {
fatalError("The dequeued cell is not an instance of TodayTableViewCell.")
}
let task = tasks[indexPath.row]
cell.nameLabel.text = task.name
cell.descriptionLabel.text = task.description
cell.timeRangeLabel.text = task.timeRangeLabel
cell.currentTime.text = String(format:"%f", task.currentTime)
cell.totalTime.text = String(format:"%f", task.totalTime)
cell.taskIcon.image = task.icon
cell.loadingIcon = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
cell.loadingIcon.hidesWhenStopped = true
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt
indexPath: IndexPath){
let cell = (TodayTableViewCell)();tableView.cellForRow(at: indexPath)
print("tapped")
tasks[indexPath.row].isActive = !tasks[indexPath.row].isActive
if(tasks[indexPath.row].isActive) {
//Loading.start()
cell.loadingIcon.startAnimating()
}
else {
//Loading.stop()
cell.loadingIcon.stopAnimating()
}
}
I get fatal error: unexpectedly found nil while unwrapping an Optional value but I have no idea why because it looks like I am initializing it.
I get:
EXC_BAD_INSTRUCTION
Here is the storyboard:
Now back to the error I was getting earlier:
As you can see in the image, you can set that property on the storyboard. You can find on the right panel of your xcode.
If you still want to write that line you should connect the UIActivityIndicator to the IBOutlet