bugfix> ios > 投稿

TokenView(Chip view)スタイルのビューを実現したい。このため、UITableViewCell内でコレクションビューを使用していますが、CollectionViewにはカスタムセルがあります。カスタムセル内には UILabel 。セルの幅は UILabel のコンテンツに依存するようになりました 。

以下は、カスタムUITableViewCellセルのコードです

import UIKit
class LanguageTableViewCell: UITableViewCell,UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{
        var arr:[String] = ["English","Intermediate","English","Intermediate","English","Intermediate","English","Intermediate","English","Intermediate","English","Intermediate","English","Intermediate","English","Intermediate","English","Intermediate","English","Intermediate","English","Intermediate"]
    @IBOutlet weak var collectionView: UICollectionView!
    override func awakeFromNib() {
        super.awakeFromNib()
        collectionView.dataSource = self
        collectionView.delegate = self
        let layout = UICollectionViewFlowLayout()
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        layout.scrollDirection = .vertical
        self.collectionView.collectionViewLayout = layout
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return arr.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "LanguageCollectionViewCell", for: indexPath) as! LanguageCollectionViewCell
        cell.setValue(lang: arr[indexPath.row],indexPath:indexPath)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let string = arr[indexPath.row]
        let width = (string.count * 10)
        return CGSize(width:width, height: 30)
    }
}

UICollectionViewCell のクラス

typealias Parameters = [String:Any]
import UIKit

class LanguageCollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var languageLabel: UILabel!
    override func layoutSubviews() {
        super.layoutSubviews()
    }
    func setValue(lang:String ,indexPath:IndexPath) {
        if indexPath.row % 2 == 0 {
            languageLabel.backgroundColor = UIColor.gray
        }else {
            languageLabel.backgroundColor = UIColor.yellow
        }
            self.languageLabel.text = lang
    }
}

回答 4 件
  • これを UITableViewCell Cell に実装します

    UICollectionViewFlowLayout のサブクラス化

    そのような実装を追加します。

    解決策は、セル間隔の縮小/ UICollectionViewセルレイアウトの整列です。非常にシンプルで迅速なパフォーマンス。 Olloquiの例に基づく

    クラスCustomViewFlowLayout

    class CustomViewFlowLayout: UICollectionViewFlowLayout {
    let cellSpacing:CGFloat = 4
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
                self.minimumLineSpacing = 4.0
                self.sectionInset = UIEdgeInsets(top: 10, left: 8, bottom: 10, right: 6)
                let attributes = super.layoutAttributesForElements(in: rect)
                var leftMargin = sectionInset.left
                var maxY: CGFloat = -1.0
                attributes?.forEach { layoutAttribute in
                    if layoutAttribute.frame.origin.y >= maxY {
                        leftMargin = sectionInset.left
                    }
                    layoutAttribute.frame.origin.x = leftMargin
                    leftMargin += layoutAttribute.frame.width + cellSpacing
                    maxY = max(layoutAttribute.frame.maxY , maxY)
                }
                return attributes
        }
    }
    
    

    cellSpacingは、任意の値に設定できます。このトリックにより、セル間のスペースがcellSpacingと正確に等しくなることが保証されます。

    UITableViewCell Cell/CollectionViewControllerの実装。

    import UIKit
    class ViewController: UIViewController , UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
    @IBOutlet weak var collectionView: UICollectionView!
    var arr:[String] = ["English","Intermediate","English","English","arr","UICollectionViewFlowLayoutFlowFlowFlow","English","UICollectionViewDelegate","English","Intermediate","UIViewController","viewDidLoad","Intermediate","String","Intermediate","arr","Intermediate","UIKit","Intermediate","English","columnLayout","English","languageLabel"]
    let columnLayout = CustomViewFlowLayout()
    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.collectionViewLayout = columnLayout
        collectionView.contentInsetAdjustmentBehavior = .always
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return arr.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "chip", for: indexPath) as! LanguageCollectionViewCell
        cell.languageLabel.text = arr[indexPath.row]
        return cell
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let string = arr[indexPath.row]
        // your label font.
        let font = UIFont.systemFont(ofSize: 16)
        let fontAttribute = [NSAttributedStringKey.font: font]
        // to get the exact width for label according to ur label font and Text.
        let size = string.size(withAttributes: fontAttribute)
        // some extraSpace give if like so.
        let extraSpace : CGFloat = 8.0
        let width = size.width + extraSpace
        return CGSize(width:width, height: 30)
       }
    }
    
    

    UICollectionViewCell のクラス

    class LanguageCollectionViewCell: UICollectionViewCell {
        @IBOutlet weak var languageLabel: UILabel!
    }
    
    

  • 1実装UICollectionViewDelegateFlowLayoutプロトコル、

    次のコードを追加します。

    var itemsPerRow:CGFloat = 3

    let sectionInsets = UIEdgeInsets(上:10、左:10、下:10、右:10)

    次に、デリゲートメソッドを追加して、次のような間隔を決定します。

    func collectionView(_ collectionView: UICollectionView,
                            layout collectionViewLayout: UICollectionViewLayout,
                            sizeForItemAt indexPath: IndexPath) -> CGSize {
            let paddingSpace = sectionInsets.left * (itemsPerRow + 1)
            let availableWidth = view.frame.width - paddingSpace
            let widthPerItem = availableWidth / itemsPerRow
            return CGSize(width: widthPerItem, height: widthPerItem)
        }
        func collectionView(_ collectionView: UICollectionView,
                            layout collectionViewLayout: UICollectionViewLayout,
                            insetForSectionAt section: Int) -> UIEdgeInsets {
            return sectionInsets
        }
        func collectionView(_ collectionView: UICollectionView,
                            layout collectionViewLayout: UICollectionViewLayout,
                            minimumLineSpacingForSectionAt section: Int) -> CGFloat {
            return 10
        }
    
    

  • 私は同じためにポッドを使用しました

    pod 'AlignedCollectionViewFlowLayout'
    
    

    そして、私は私の UICollectionView を使用するクラスで 、

    import AlignedCollectionViewFlowLayout
    
    

    次のようにcollectionViewLayoutを構成しました

    if let fl = myCollection.collectionViewLayout as? AlignedCollectionViewFlowLayout {          
      fl.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
      fl.horizontalAlignment = .left
      fl.verticalAlignment = .top
    }
    
    

    Note that you can set left/right and top/bottom alignments with this pod! It works like a charm for me

    preferredMaxLayoutWidth を追加することも確認しました   UICollectionViewCell のラベルに  可能なエラーの1つを修正できるように(つまり、セルの幅を画面サイズより大きくすることはできません)

    class MyCollectionViewCell: UICollectionViewCell {
        override func awakeFromNib() {
            super.awakeFromNib()
            // Initialization code
            myLabel.preferredMaxLayoutWidth = UIScreen.main.bounds.size.width * 0.8
        }
    }
    
    

    そして、私のコレクションに対して次のような結果が得られます。

  • 試してもらえますか

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let lb = UILabel()
        lb.text = arr[indexPath.row]
        lb.font = UIFont.init(name: "System", size: 17)
        lb.sizeToFit()
        return CGSize(width:lb.frame.size.width, height: 30 )
    }
    
    

    //

    またはこれを設定する

    layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
    
    

    セルにラベル0から始まるリーディング、トレーリング、トップおよびボトム制約を与えます

    注意: どちらの場合でも、メソッド sizeForItemAt の実装を削除する必要があります

あなたの答え