1

I have class for a cell

import UIKit

class LinkCellView: UITableViewCell {
    @IBOutlet weak var cellTitleLabel: UILabel!
    @IBOutlet weak var tagsListView: UIView!

    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
    }

}

Table View Cell in IB

I fill the tagsListView in cellForRowAt

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "linkCell", for: indexPath) as! LinkCellView
    let object = links[indexPath.row]

    cell.cellTitleLabel!.text = object.description
    let tag = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
    tag.text = "Frkul"
    cell.tagsListView.addSubview(tag)

    return cell
}

Unfortunately when I then run the app in simulator, list of tags is just barely visible there. My expectation is to see the whole tags list.

Resulting cell on iOS

I am pretty new to iOS development, so it is possible I am missing some fundamental knowledge of designing iOS UI. If it is not possible to answer this question directly, pls point me to a tutorial / webinar taking newbies through this topic.

  • Xcode Version 10.0
  • iOS 12
  • iOS simulator Version 10.0

Static version of the App — https://gitlab.com/lipoqil/stackview-in-table-cell

Mailo Světel
  • 24,002
  • 5
  • 30
  • 40

3 Answers3

1

Ok, for some reason, if I use UIStackView, instead of UIView, it displays almost as I wish.

Table rows in simulator

It introduces one change in the code

cell.tagListView.addSubview(tag)cell.tagListView.addArrangedSubview(tag)

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "linkCell", for: indexPath) as! LinkCellView
    cell.tagListView.subviews.forEach { $0.removeFromSuperview() }
    let object = links[indexPath.row]

    cell.cellTitleLabel!.text = object.description
    let tag = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
    tag.shadowColor = .blue
    tag.text = object.tags
    cell.tagListView.addArrangedSubview(tag)

    return cell
}

I still need to solve, how to fit the tags there, how to make its look more tagish, but I believe that's beyond the original question.

Mailo Světel
  • 24,002
  • 5
  • 30
  • 40
0

if you have a collection of tags you need to implement a collection view into your tableView Cell, and if you just have 1 tag, just implement it in your xib ?

Mahgolsadat Fathi
  • 3,107
  • 4
  • 16
  • 34
  • It seems to me collection view is for grid visualisation of a data. As the tags will vary in length, I don't UICollectionView to be a good fit for this task. Or is it somehow possible to make it non-grid? Sry for dumb questions, almost everything is new for me in iOS development – Mailo Světel Oct 23 '18 at 19:10
  • 1
    yes of course it is possible! UI collection view is a kinda Scrolling view which supports horizontal scrolling and in fact, the grids are also collection views with vertical scrolling direction, and it looks actually grid because of sizing the width of each cell, for example u can set each cell's width = screenWidth/3 for or any number, I have also used collection views for dynamic tags, or showing winners list and .... in my apps :) – Mahgolsadat Fathi Oct 24 '18 at 15:40
0

Here is my code.

func numberOfSections(in tagsCV: UICollectionView) -> Int {
    return 1
}

func collectionView(_ tagsCV: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return videoObject?.tags?.count ?? 0
}

func collectionView(_ tagsCV: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
    let fontAttributes = [NSAttributedStringKey.font: StylesBook.hashtag.value.textFont]
    let size = (videoObject?.tags?[indexPath.row] ?? "" as String).size(withAttributes: fontAttributes)
    return CGSize(width: size.width + CGFloat(20) , height: 50)

}

func collectionView(_ tagsCV: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = tagsCV.dequeueReusableCell(withReuseIdentifier: "TagCollectionViewCell", for: indexPath) as! TagCollectionViewCell
    cell.tagBtn.setTitle(englishNumToPersian(text: videoObject?.tags?[indexPath.row] ?? "")  , for: .normal)
    cell.tagBtn.addTarget(self, action: #selector(tagTaped(sender:)), for: .touchDown)
    cell.transform = CGAffineTransform(scaleX: -1, y: 1)
    return cell
}

The key is that you need to set ur collection view's scroll direction horizontal. This way whether you have 1 or 1000 tag, they'll all be shown perfectly, and the button (or label) width will fit its content. I recommend you to use button, instead of label, and disable its user interaction to act like a label.

Mailo Světel
  • 24,002
  • 5
  • 30
  • 40
Mahgolsadat Fathi
  • 3,107
  • 4
  • 16
  • 34
  • I don't think I am able to make this go. I ended up with app which fails shortly after it's launched with uncaught exception which doesn't tell me anything. You can check — https://gitlab.com/lipoqil/stackview-in-table-cell/compare/master...collection-view – Mailo Světel Oct 27 '18 at 20:14