creating custom tableview cells in swift

2019-01-02 18:11发布

I have a custom cell class with a couple of IBOutlets. I have added the class to the storyboard. I have connected all my outlets. my cellForRowAtIndexPath function looks like this:

override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as SwipeableCell

        cell.mainTextLabel.text = self.venueService.mainCategoriesArray()[indexPath.row]

        return cell
    }

Here is my custom cell class:

class SwipeableCell: UITableViewCell {
    @IBOutlet var option1: UIButton
    @IBOutlet var option2: UIButton
    @IBOutlet var topLayerView : UIView
    @IBOutlet var mainTextLabel : UILabel
    @IBOutlet var categoryIcon : UIImageView

    init(style: UITableViewCellStyle, reuseIdentifier: String!) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)


    }
}

When I run the app, all my cell are empty. I have logged out self.venueService.mainCategoriesArray() and it contains all the correct strings. I have also tried putting an actual string equal to the label, and that produces the same result.

What am I missing? Any help is appreciated.

10条回答
孤独总比滥情好
2楼-- · 2019-01-02 18:18

Thanks for all the different suggestions, but I finally figured it out. The custom class was set up correctly. All I needed to do, was in the storyboard where I choose the custom class: remove it, and select it again. It doesn't make much sense, but that ended up working for me.

查看更多
呛了眼睛熬了心
3楼-- · 2019-01-02 18:21

This is for who are working custom cell with .xib

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{

    let identifier = "Custom"

    var cell: CustomCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomCel  

      if cell == nil {
            tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: identifier)
           cell =tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomCell
        }return cell}
查看更多
怪性笑人.
4楼-- · 2019-01-02 18:24

[1] First Design your tableview cell in StoryBoard.

[2] Put below table view delegate method

//MARK: - Tableview Delegate Methods

func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{

    return <“Your Array”>
}


func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{

    var totalHeight : CGFloat = <cell name>.<label name>.frame.origin.y    

    totalHeight +=   UpdateRowHeight(<cell name>.<label name>, textToAdd: <your array>[indexPath.row])    

    return totalHeight
}


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{


    var cell : <cell name>! = tableView.dequeueReusableCellWithIdentifier(“<cell identifire>”, forIndexPath: indexPath) as! CCell_VideoCall

    if(cell == nil)
    {
        cell = NSBundle.mainBundle().loadNibNamed("<cell identifire>", owner: self, options: nil)[0] as! <cell name>;
    }


    <cell name>.<label name>.text = <your array>[indexPath.row] as? String



    return cell as <cell name>
}

//MARK: - Custom Methods

func UpdateRowHeight ( ViewToAdd : UILabel , textToAdd : AnyObject  ) -> CGFloat{


    var actualHeight : CGFloat = ViewToAdd.frame.size.height

    if let strName : String? = (textToAdd as? String)
        where !strName!.isEmpty
    {

        actualHeight = heightForView1(strName!, font: ViewToAdd.font, width: ViewToAdd.frame.size.width, DesignTimeHeight: actualHeight )

    }
    return actualHeight
}
查看更多
余生无你
5楼-- · 2019-01-02 18:26

I have the same problem.

Generally what I did is the same with you.

class dynamicCell: UITableViewCell {

    @IBOutlet var testLabel : UILabel

    init(style: UITableViewCellStyle, reuseIdentifier: String) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

and in the uitableviewcell method:

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    var cell :dynamicCell = tableView.dequeueReusableCellWithIdentifier("cell") as dynamicCell

    cell.testLabel.text = "so sad"

    println(cell.testLabel)

    return cell;
}

and yeah the tableview show nothing! But guess what it actually show something...because the log I get from the println(cell.testLabel) shows that all the Labels are actually displayed out.

BUT! their Frames is strange, which have something like this:

frame = (0 -21; 42 21);

so it has a (0,-21) as (x,y), so that means the label is just appear at somewhere outside the bound of the cell.

so I try to add adjust the frame manually like this:

cell.testLabel.frame = CGRectMake(10, 10, 42, 21)

and sadly, it doesn't work.

---------------update after 10 min -----------------

I DID IT. so, it seems that the problem comes from the Size Classes.

Click on your .storyboard file and go to the File Inspector Tab

UNCHECK THE Size Classes checkbox

and finally my "so sad"Label come out!

查看更多
零度萤火
6楼-- · 2019-01-02 18:29

Uncheck "Size Classes" checkbox works for me as well, but you could also add the missing constraints in the interface builder. Just use the built-in function if you don't want to add the constraints on your own. Using constraints is - in my opinion - the better way because the layout is independent from the device (iPhone or iPad).

查看更多
怪性笑人.
7楼-- · 2019-01-02 18:33

Set tag for imageview and label in cell

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    return self.tableData.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{

    let cell = tableView.dequeueReusableCellWithIdentifier("imagedataCell", forIndexPath: indexPath) as! UITableViewCell

    let rowData = self.tableData[indexPath.row] as! NSDictionary

    let urlString = rowData["artworkUrl60"] as? String
    // Create an NSURL instance from the String URL we get from the API
    let imgURL = NSURL(string: urlString!)
    // Get the formatted price string for display in the subtitle
    let formattedPrice = rowData["formattedPrice"] as? String
    // Download an NSData representation of the image at the URL
    let imgData = NSData(contentsOfURL: imgURL!)


    (cell.contentView.viewWithTag(1) as! UIImageView).image = UIImage(data: imgData!)

    (cell.contentView.viewWithTag(2) as! UILabel).text = rowData["trackName"] as? String

    return cell
}

OR

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "imagedataCell")

    if let rowData: NSDictionary = self.tableData[indexPath.row] as? NSDictionary,
        urlString = rowData["artworkUrl60"] as? String,
        imgURL = NSURL(string: urlString),
        formattedPrice = rowData["formattedPrice"] as? String,
        imgData = NSData(contentsOfURL: imgURL),
        trackName = rowData["trackName"] as? String {
            cell.detailTextLabel?.text = formattedPrice
            cell.imageView?.image = UIImage(data: imgData)
            cell.textLabel?.text = trackName
    }

    return cell
}

see also TableImage loader from github

查看更多
登录 后发表回答