The UIImageView is not showing the image up in my custom UITableViewCell.
Can't figure out why, I have tried both methods of setting the Image property it in the Interface Builder and then tried setting up an IBOutlet and setting the .image property.
None seem to work. Why is this happening to me?!?!
Class with TableViewDataSource
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("LatestMessageCell") as LatestMessageCell
cell.avatarImageView.image = UIImage(named: "Logo")
return cell
}
Custom Cell Class
class LatestMessageCell: UITableViewCell {
#IBOutlet weak var cardBackgroundView: UIView!
#IBOutlet weak var avatarImageView: UIImageView!
#IBOutlet weak var usernameLabel: UILabel!
#IBOutlet weak var messageLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
cardBackgroundView.layer.cornerRadius = 4
cardBackgroundView.layer.shadowColor = UIColor.blackColor().CGColor
cardBackgroundView.layer.shadowOffset = CGSize(width: 0, height: 2)
cardBackgroundView.layer.shadowOpacity = 0.3
cardBackgroundView.layer.shadowRadius = 5
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Pls modify your Method and check:
let simpleTableIdentifier = "TableViewCell";
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell:LatestMessageCell? = tableView.dequeueReusableCellWithIdentifier(simpleTableIdentifier) as? LatestMessageCell
if (cell == nil)
{
let nib:Array = NSBundle.mainBundle().loadNibNamed("LatestMessageCell", owner: self, options: nil)
cell = nib[0] as? LatestMessageCell
}
cell!.avatarImageView.image = UIImage(named: "Logo")
return cell!
}
Related
I have a table view with expanding cells. The expanding cells come from a xib file. In the class of the table is where all of the code is that controls the expansion and pulling data from plist. I'm trying to add a close button but only want it to show when the cell is expanded. As it stands, I can't reference the button to hide it because it's in another class. Here is how I am trying to access it:
import UIKit
class SecondPolandViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var customTableViewCell:CustomTableViewCell? = nil
var items = [[String:String]]()
override func viewDidLoad() {
super.viewDidLoad()
**REFERENCING CLASS**
customTableViewCell = CustomTableViewCell()
let nib = UINib.init(nibName: "CustomTableViewCell", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier: "cell")
self.items = loadPlist()
}
func loadPlist()->[[String:String]]{
let path = Bundle.main.path(forResource: "PolandResourceList", ofType: "plist")
return NSArray.init(contentsOf: URL.init(fileURLWithPath: path!)) as! [[String:String]]
}
var selectedIndex:IndexPath?
var isExpanded = false
func didExpandCell(){
self.isExpanded = !isExpanded
self.tableView.reloadRows(at: [selectedIndex!], with: .automatic)
}
}
extension SecondPolandViewController:UITableViewDataSource, UITableViewDelegate{
***HIDING BUTTON***
let button = customTableViewCell?.closeButton
button?.isHidden = true
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.selectedIndex = indexPath
self.didExpandCell()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
cell.selectionStyle = .none
let item = self.items[indexPath.row]
cell.titleLabel.text = item["title"]
cell.shortLabel.text = item["short"]
cell.otherImage.image = UIImage.init(named: item["image"]!)
cell.thumbImage.image = UIImage.init(named: item["image"]!)
cell.longLabel.text = item["long"]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let height = UIScreen.main.bounds.height
if isExpanded && self.selectedIndex == indexPath{
//return self.view.frame.size.height * 0.6
return 400
}
return 110
//return height * 0.2
}
}
This does not hide it though.
Here is the xib that I am calling from if it helps. It is probably simple, I am just a newly self taught developer.
import UIKit
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var closeButton: UIImageView!
#IBOutlet weak var otherImage: UIImageView!
#IBOutlet weak var thumbImage: UIImageView!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var shortLabel: UILabel!
//#IBOutlet weak var longLabel: UITextView!
#IBOutlet weak var longLabel: UITextView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
//let width = UIScreen.main.bounds.width
//let height = UIScreen.main.bounds.height
//thumbImage.frame.size.width = height * 0.19
//thumbImage.frame.size.height = height * 0.19
}
}
It seems like that you just need to add these lines into cellForRowAt:indexPath method:
if indexPath == selectedIndexPath {
cell.closeButton.isHidden = false
} else {
cell.closeButton.isHidden = true
}
You may add them right before return line
The normal iOS answer for this is a delegate, but you could get away with a simple closure in this case.
In CustomTableViewCell, add
public var closeTapped: ((CustomTableViewCell) -> ())?
Then in that class, when close is tapped, call
self.closeTapped?(self)
In the VC, in cellForRowAt,
cell.closeTapped = { cell in
// do what you want with the VC
}
For delegates, this might help: https://medium.com/#jamesrochabrun/implementing-delegates-in-swift-step-by-step-d3211cbac3ef
The quick answer to why to prefer delegates over the closure is that its a handy way to group a bunch of these together. It's what UITableViewDelegate is (which you are using). Also, it's a common iOS idiom.
I wrote about this here: https://app-o-mat.com/post/how-to-pass-data-back-to-presenter for a similar situation (VC to VC communication)
My storyboard looks like this
and my code is the following
UIViewController
class DownLoadSoundsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// MARK: View Controller Properties
let viewName = "DownLoadSoundsViewController"
#IBOutlet weak var visualEffectView: UIVisualEffectView!
#IBOutlet weak var dismissButton: UIButton!
#IBOutlet weak var downloadTableView: UITableView!
// MARK: Properties
var soundPacks = [SoundPack?]() // structure for downloadable sounds
override func viewDidLoad() {
super.viewDidLoad()
downloadTableView.dataSource = self
downloadTableView.delegate = self
downloadTableView.register(DownLoadTableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfSoundPacks
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let method = "tableView.cellForRowAt"
//if (indexPath as NSIndexPath).section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "downloadTableViewCell", for: indexPath) as! DownLoadTableViewCell
cell.backgroundColor = UIColor.green
if soundPacks[(indexPath as NSIndexPath).row]?.price == 0 {
cell.soundPackPriceUILabel.text = "FREE"
} else {
cell.soundPackPriceUILabel.text = String(format: "%.2", (soundPacks[(indexPath as NSIndexPath).row]?.price)!)
}
//cell.textLabel?.text = soundPacks[(indexPath as NSIndexPath).row]?.soundPackTitle
cell.soundPackTitleUILabel.text = soundPacks[(indexPath as NSIndexPath).row]?.soundPackTitle
cell.soundPackAuthorUILabel.text = soundPacks[(indexPath as NSIndexPath).row]?.author
cell.soundPackShortDescription.text = soundPacks[(indexPath as NSIndexPath).row]?.shortDescription
cell.soundPackImage.image = UIImage(named: "Placeholder Icon")
DDLogDebug("\(viewName).\(method): table section \((indexPath as NSIndexPath).section) row \((indexPath as NSIndexPath).row))")
return cell
//}
}
UItableViewCell
class DownLoadTableViewCell: UITableViewCell {
#IBOutlet weak var soundPackImage: UIImageView!
#IBOutlet weak var soundPackTitleUILabel: UILabel!
#IBOutlet weak var soundPackAuthorUILabel: UILabel!
#IBOutlet weak var soundPackShortDescription: UILabel!
#IBOutlet weak var soundPackPriceUILabel: UILabel!
let gradientLayer = CAGradientLayer()
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
}
}
But I get the following;
I am sure I am doing something small incorrectly, but as of yet can't figure it out. Looked through many examples included my own code where I have gotten this working before.
Not a single one of my settings for the tableview are getting invoked except the number of cells. But everything in;
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{...}
is not working.
Help is appreciated.
I think you need to reload the tableView after getting data from Firebase
self.saveMixesTableView.reloadData()
I have this custom UITableViewCell:
class CircleOfTrustTableViewCell: UITableViewCell {
#IBOutlet var permissionTitle: UILabel!
#IBOutlet weak var permissionImage: UIImageView!
#IBOutlet weak var permissionSwitch: UISwitch!
#IBOutlet weak var spacingView: UIView!
// Update toggle based on user visibility and category type
func update(showUser: Bool, index: Int){
self.tag = index
let type = ProfileContentTypeActual.all[index]
self.permissionImage.image = UIImage(named: categoryImages[type]!)
self.permissionTitle.text = categoryNames[type]
if showUser {
self.permissionSwitch.tag = index
self.permissionSwitch.isEnabled = true
if let toggles = GlintUser.getThisUser().trust_toggle {
self.permissionSwitch.setOn(toggles.getState(type), animated: true)
}
} else {
self.permissionSwitch.setOn(false, animated: true)
self.permissionSwitch.isEnabled = false
}
}
}
I implement the cell this way:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
settingsTableView.register(UINib(nibName: "COTTableViewCell", bundle: nil), forCellReuseIdentifier: "cotCell")
let cotCell = (settingsTableView.dequeueReusableCell(withIdentifier: "cotCell") as! CircleOfTrustTableViewCell)
cotCell.update(showUser: showUser, index: indexPath.row)
return cotCell
}
My question is: Is it best practice to call the update function on the cell (to populate its data) or is it best to leave this in the cellForRowAtIndexPath method?
I have a table layout inside a view which as a custom cell,The problem I'm facing is that the cells inside has a button i want to hide the button in cell on clicking it(only the one that is clicked should be hidden) how can i do thing in correct method?
ScrollCell.swift
class ScrollCell: UITableViewCell {
#IBOutlet weak var ProfilePic: SpringImageView!
#IBOutlet weak var UserName: SpringButton!
#IBOutlet weak var Closet: UILabel!
#IBOutlet weak var Style: UILabel!
//------//
#IBOutlet weak var MianImg: UIImageView!
//-------//
#IBOutlet weak var ProductName: UILabel!
#IBOutlet weak var LoveCount: UIButton!
#IBOutlet weak var Discount: UILabel!
#IBOutlet weak var OrginalPrice: UILabel!
#IBOutlet weak var Unliked: UIButton!
#IBOutlet weak var Liked: UIButton!
#IBOutlet weak var Comment: UIButton!
#IBOutlet weak var Share: SpringButton!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func layoutSubviews() {
ProfilePic.layer.cornerRadius = ProfilePic.bounds.height / 2
ProfilePic.clipsToBounds = true
}
}
ScrollController.swift
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1 // however many sections you need
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(try! Realm().objects(Feed))
var FeedModel = Feed()
let realm = try! Realm()
let tan = try! Realm().objects(Feed).sorted("ID", ascending: false)
return tan.count // however many rows you need
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// get an instance of your cell
cell = tableView.dequeueReusableCellWithIdentifier("ScrollCellDqueue", forIndexPath: indexPath) as! ScrollCell
IndexPath = indexPath.row
var FeedModel = Feed()
let realm = try! Realm()
let tan = try! Realm().objects(Feed).sorted("ID", ascending: false)
cell.ProfilePic.kf_setImageWithURL(NSURL(string:tan[indexPath.row].ProfilePic)!)
cell.UserName.setTitle(tan[indexPath.row].FullName, forState: .Normal)
cell.Style.text = tan[indexPath.row].StyleType
if tan[indexPath.row].UserType == "store_front"{
cell.Closet.text = "Store Front"
}else if tan[indexPath.row].UserType == "normal"{
cell.Closet.text = "Pri Loved"
}
//-----//
var SingleImage:String = ""
var ImageArray = tan[indexPath.row].ImageArraySet.componentsSeparatedByString(",")
SingleImage = ImageArray[0]
cell.MianImg.kf_setImageWithURL(NSURL(string:SingleImage)!)
//-----//
cell.ProductName.text = tan[indexPath.row].ItemName
cell.OrginalPrice?.text = "\(tan[indexPath.row].OrginalPrice)"
cell.LoveCount.setTitle("\(tan[indexPath.row].LikeCount)"+" Loves", forState: .Normal)
cell.Discount.text = "\(tan[indexPath.row].Discount)"+" % off"
if(tan[indexPath.row].LikeStatus){
cell.Unliked.hidden = true
cell.Liked.hidden = false
}
else if (!tan[indexPath.row].LikeStatus){
cell.Unliked.hidden = false
cell.Liked.hidden = true
}
cell.Unliked.tag = tan[indexPath.row].ID
cell.Liked.tag = tan[indexPath.row].ID
return cell
}
#IBAction func LikeBtn(sender: AnyObject) {
print(sender.tag)
print(IndexPath)
//here i want to know who i can hide the button i have clicked ?
}
Here i want to access the cell in which button is clicked and make changes to UI item inside that cell how can i do that ?
There are many ways to do it. One possible solution is use block.
Add this to ScrollCell
var didLikedTapped: (() -> Void)?
and receive the event of the LikedButton in the cell
#IBAction func LikeBtn(sender: AnyObject) {
didLikedTapped?()
}
Then in cellForRowAtIndexPath of viewController add this
cell.didLikedTapped = {[weak self] in
print(IndexPath)
}
Liked is uibutton in ScrollCell, i don't known, why can you add IBAction for it in ScrollController? . You must implement it in ScrollCell And code:
#IBAction func LikeBtn(sender: UIButton) {
print(sender.tag)
sender.hiden = true
}
And i think, if you have only one UIbutton, it will better. In there, like and unlike is 2 state of uibutton(seleted and none). When you click the button, change it's state
Update:
class sampleCell: UITableViewCell{
#IBOutlet var btnLike : UIButton!
#IBOutlet var btnUnLike : UIButton! // frame of 2 button is equal
override func awakeFromNib() {
super.awakeFromNib()
self.btnUnLike.hidden = true
// ...
}
func updateData(data:AnyObject){ // data's type is Feed
// set data for cell
// i think you should implement in here. and in ScollController call : cell.updateData() , it's better
/* e.x
self.ProductName.text = tan[indexPath.row].ItemName
self.OrginalPrice?.text = "\(tan[indexPath.row].OrginalPrice)"
self.LoveCount.setTitle("\(tan[indexPath.row].LikeCount)"+" Loves", forState: .Normal)
self.Discount.text = "\(tan[indexPath.row].Discount)"+" % off"
*/
}
#IBAction func likeTap(sender:UIButton){ // rememeber set outlet event for btnLike and btnUnLike is this function
if sender == self.btnLike{
self.btnLike.hidden = true
self.btnUnLike.hidden = false
// do s.t
}else if sender == self.btnUnLike{
self.btnLike.hidden = false
self.btnUnLike.hidden = true
// do s.t
}
}
}
Check if the following code help
#IBAction func LikeBtn(sender: AnyObject) {
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(position)
let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
UITableViewCell
print(indexPath?.row)
}
give the LikeBtn the property indexpath, in cellForRowAtIndexPath method, pass the indexPath to the LikeBtn, then you will know which cell's LikeBtn clicked.
class LikeBtn: UIButton {
var indexPath: NSIndexPath?
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
// here pass the indexpath to your button
cell.likeBtn.indexPath = indexPath
return cell
}
#IBAction func likeTap(sender: LikeBtn){
if let indexPath = sender.indexPath {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
//here you will know the exact cell, now you can hide or show your buttons
}
}
}
I'm trying to create a tableview with custom cells that each one holds a tableview.
I want to show the inner tableview just when it have some data (most of the time it's empty). I've managed to display the cells but can't display their tableview if it's populated with data.
The problem also is that the cell height needs to be dynamic according to the amount of data to display.
The cell code:
class feedViewCell: UITableViewCell , UITableViewDataSource , UITableViewDelegate {
#IBOutlet var feedCellImage: UIImageView!
#IBOutlet var feedCellUserName: UILabel!
#IBOutlet var feedCellDate: UILabel!
#IBOutlet var feedCellComments: UILabel!
#IBOutlet var cardView: UIView!
#IBOutlet var repliesTableView: UITableView!
var repliesArray:[Reply] = []
#IBAction func addComment(sender: AnyObject) {
}
override func awakeFromNib() {
super.awakeFromNib()
var nib = UINib(nibName: "feedComment", bundle: nil)
repliesTableView.registerNib(nib, forCellReuseIdentifier: "commentCell")
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
override func layoutSubviews() {
cardSetup()
}
func cardSetup() {
cardView.layer.masksToBounds = false
cardView.layer.cornerRadius = 5
cardView.layer.shadowOffset = CGSizeMake(-0.2, 0.2)
cardView.layer.shadowRadius = 1
cardView.layer.shadowOpacity = 0.2
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return repliesArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = repliesTableView.dequeueReusableCellWithIdentifier("commentCell", forIndexPath: indexPath) as CommentFeedCell
cell.commentCellUserName.text = repliesArray[indexPath.row].userName
return cell
}
}
And the Main controller code:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var comment = comments[indexPath.row]
let cell: feedViewCell = tableView.dequeueReusableCellWithIdentifier("feedCell", forIndexPath: indexPath) as feedViewCell
cell.feedCellUserName.text = comment.userName
cell.feedCellImage.backgroundColor = UIColor.redColor()
cell.feedCellComments.text = "\(comment.replies.count) COMMENTS"
cell.repliesArray = comment.replies
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyy"
cell.feedCellDate.text = dateFormatter.stringFromDate(NSDate())
if cell.repliesArray.count > 0 {
cell.repliesTableView.rowHeight = UITableViewAutomaticDimension
}
cell.repliesTableView.reloadData()
return cell
}
How to show the inner tableview only in cells which have comments (and hiding the tableview in cells with 0 comments)?
Call super in layoutSubviews and let us know what happens.
override func layoutSubviews() {
super.layoutSubviews()
cardSetup()
}