簡體   English   中英

自定義單元格中自定義 UITableViewCell 內的多個 UIStackViews 沒有 Storyboard 不起作用

[英]Multiple UIStackViews inside a custom UITableViewCell in Custom Cell without Storyboard not working

我目前正在我的應用程序中構建一個屏幕,它基本上是一個包含 3 個部分的長 UITableView,每個部分都有不同數量的獨特自定義單元格。 設置 tableview 工作正常,我在單元格中添加了一些隨機文本以確保每個單元格都被正確調用和定位。 我已經從我的項目中完全刪除了我的故事板,因為它會因為某些原因導致以后出現問題。 所以我不能通過故事板做任何事情。

下一步是構建自定義單元格。 作為初學者,其中一些對我來說相當復雜。 這是我的細胞之一: 我的細胞之一的示例

我想在多個 UIStackViews 中拆分單元格,一個用於圖片和名稱,另一個用於右側的統計信息,它本身將包含兩個堆棧視圖,其中包含兩行統計信息中的每一行。 然后每個都可以包含另一個嵌入的 stackview,里面有兩個 uiLabels,數字和描述。 最重要的是一個切換按鈕。

我似乎無法理解如何定義這一切。 正如我所說,我定義了 Tableview 並在我的cellForRowAt調用了正確的單元格,如下所示,例如:

if indexPath.row == 0 && indexPath.section == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: StatsOverViewCell.identifier, for: indexPath) as! StatsOverViewCell
        cell.configure()
        return cell
} else if ...

我為每個單元格創建了文件,其中之一是 StatsOverViewCell。 在這個文件中,我有一個與類同名的標識符。 我還添加了我從 tableview 調用的 configure 函數,layoutSubviews 函數,用於在單元格內部布局視圖,並且我已經初始化了我需要的每個標簽和圖像。 我已將文件精簡為幾個示例,以節省您的時間:

class StatsOverViewCell: UITableViewCell {

//Set identifier to be able to call it later on
static let identifier = "StatsOverViewCell"

let myProfileStackView = UIStackView()
let myImageView = UIImageView()
let myName = UILabel()
let myGenderAndAge = UILabel()

let myStatsStackView = UIStackView()

let oneView = UIStackView()
let oneStat = UILabel()
let oneLabel = UILabel()

let twoStackView = UIStackView()
let twoStat = UILabel()
let twoLabel = UILabel()

//Do this for each of the labels I have in the stats

public func configure() {
    myImageView.image = UIImage(named: "person-icon")
    myName.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    myImageView.contentMode = .scaleAspectFill
    myName.text = "Name."
    myName.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    myName.textAlignment = .center
    //Add the Name label to the stackview
    myProfileStackView.addArrangedSubview(myName)
    myProfileStackView.addArrangedSubview(myImageView)
    myName.centerXAnchor.constraint(equalTo: myProfileStackView.centerXAnchor).isActive = true
    
    oneStat.text = "5.187"
    oneStat.font = UIFont(name: "montserrat", size: 18)
    oneLabel.text = "Text"
    oneLabel.font = UIFont(name: "montserrat", size: 14)
}

//Layout in the cell
override func layoutSubviews() {
    super.layoutSubviews()
    contentView.backgroundColor = Utilities.hexStringToUIColor(hex: "#3F454B")
    contentView.layer.borderWidth = 1
    
    //Stackview
    contentView.addSubview(myProfileStackView)
    myProfileStackView.axis = .vertical
    myProfileStackView.distribution = .equalSpacing
    myProfileStackView.spacing = 3.5
    myProfileStackView.backgroundColor = .red
    
    myProfileStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 23).isActive = true
    myProfileStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 76).isActive = true
}

如您所見,我在配置方法中將所有排列的子視圖添加到堆棧視圖中,我在表視圖中創建單元格時調用該方法。 然后我在 layoutsubviews 中設置 stackviews 約束。 我沒有收到任何錯誤或任何東西。 但是該單元格顯示為完全空的。

我覺得我忘記了一些東西,或者我不明白如何使用 uistackviews 創建單元格。 我應該在哪里創建堆棧視圖,我應該在哪里將排列的子視圖添加到這個堆棧視圖以及我在 LayoutSubviews 中做什么? 我將非常感謝任何見解。 謝謝你的時間!

你做錯了幾件事......

  1. 你的 UI 元素應該在init 中創建和配置,而不是在configure()layoutSubviews()
  2. 您需要完整的約束才能為您的元素提供正確的布局

看看我對你的單元格類所做的更改。 它應該讓你上路:

class StatsOverViewCell: UITableViewCell {
    
    //Set identifier to be able to call it later on
    static let identifier = "StatsOverViewCell"
    
    let myProfileStackView = UIStackView()
    let myImageView = UIImageView()
    let myName = UILabel()
    let myGenderAndAge = UILabel()
    
    let myStatsStackView = UIStackView()
    
    let oneView = UIStackView()
    let oneStat = UILabel()
    let oneLabel = UILabel()
    
    let twoStackView = UIStackView()
    let twoStat = UILabel()
    let twoLabel = UILabel()
    
    //Do this for each of the labels I have in the stats
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    func commonInit() {
        myImageView.image = UIImage(named: "person-icon")

        // frame doesn't matter - stack view arrangedSubvies automatically
        //  set .translatesAutoresizingMaskIntoConstraints = false
        //myName.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        
        myImageView.contentMode = .scaleAspectFill
        myName.text = "Name."
        
        myName.textAlignment = .center
        
        //Add the Name label to the stackview
        myProfileStackView.addArrangedSubview(myName)
        myProfileStackView.addArrangedSubview(myImageView)
        
        // no need for this
        //myName.centerXAnchor.constraint(equalTo: myProfileStackView.centerXAnchor).isActive = true
        
        oneStat.text = "5.187"
        oneStat.font = UIFont(name: "montserrat", size: 18)
        oneLabel.text = "Text"
        oneLabel.font = UIFont(name: "montserrat", size: 14)
        
        contentView.backgroundColor = Utilities.hexStringToUIColor(hex: "#3F454B")
        contentView.layer.borderWidth = 1
        
        //Stackview
        contentView.addSubview(myProfileStackView)
        myProfileStackView.axis = .vertical
        
        // no need for equalSpacing if you're explicitly setting the spacing
        //myProfileStackView.distribution = .equalSpacing
        myProfileStackView.spacing = 3.5
        myProfileStackView.backgroundColor = .red
        
        // stack view needs .translatesAutoresizingMaskIntoConstraints = false
        myProfileStackView.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([

            // stack view leading 23-pts from contentView leading
            myProfileStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 23),

            // stack view top 76-pts from contentView top
            myProfileStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 76),
            
            // need something to set the contentView height
            
            // stack view bottom 8-pts from contentView bottom
            myProfileStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8),
            
            // set imageView width and height
            myImageView.widthAnchor.constraint(equalToConstant: 100.0),
            myImageView.heightAnchor.constraint(equalTo: myImageView.widthAnchor),

        ])
    }
    
    public func configure() {
        // here you would set the properties of your elements, such as
        //  label text
        //  imageView image
        //  colors
        //  etc
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM