Swift UITableView 的单元格堆叠

Swift UITableView's Cell Stacked

我用 swift 以编程方式创建了一个表视图。数据来自API。但我得到的是像这样堆叠的单元格:

这是我的 tableView 函数代码:

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
    cell.selectionStyle = .none
    cell.backgroundColor = .systemBackground
    
    cell.contentView.addSubview(profileUsernameView)
    cell.contentView.addSubview(profilePictureView)
    cell.contentView.addSubview(emailView)
    cell.contentView.addSubview(phoneView)

https://pastebin.com/DqhLMGs5

任何人都可以帮助我,以免我的 UITableView 再次堆叠? 谢谢

首先,创建自定义 UITableViewCell 并在其中添加视图。

class UserCell: UITableViewCell {
    
    private let profileUsernameLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
        label.numberOfLines = 0
        label.textAlignment = .left
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    private let profilePictureView: UIImageView = {
        let imgView = UIImageView()
        imgView.clipsToBounds = true
        imgView.layer.cornerRadius = 45
        imgView.translatesAutoresizingMaskIntoConstraints = false
        return imgView
    }()
    
    private let emailLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    private let phoneLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    private let locationLabel: UILabel = {
        let label = UILabel()
        label.numberOfLines = 0
        label.textAlignment = .left
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    private let registeredDateLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        defineLayout()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func prepareForReuse() {
        super.prepareForReuse()
        profilePictureView.image = nil
        profileUsernameLabel.text = nil
        locationLabel.text = nil
        phoneLabel.text = nil
        emailLabel.text = nil
        registeredDateLabel.text = nil
    }
    
    private func defineLayout() {
        NSLayoutConstraint.activate([
            profilePictureView.widthAnchor.constraint(equalToConstant: 90),
            profilePictureView.heightAnchor.constraint(equalToConstant: 90),
            profilePictureView.topAnchor.constraint(equalTo: contentView.topAnchor,constant: 5),
            profilePictureView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
            
            profileUsernameLabel.topAnchor.constraint(equalTo: profilePictureView.bottomAnchor, constant: 10),
            profileUsernameLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
            
            locationLabel.topAnchor.constraint(equalTo: profileUsernameLabel.bottomAnchor, constant: 2),
            locationLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
            
            phoneLabel.topAnchor.constraint(equalTo: locationLabel.bottomAnchor, constant: 2),
            phoneLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
            
            emailLabel.topAnchor.constraint(equalTo: phoneLabel.bottomAnchor, constant: 2),
            emailLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
            
            registeredDateLabel.topAnchor.constraint(equalTo: emailLabel.bottomAnchor, constant: 2),
            registeredDateLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
            
            contentView.heightAnchor.constraint(greaterThanOrEqualToConstant: 350)
        ])
    }
    
    func setUser(with data: UserModel) {
        self.profilePictureView.load(url: URL(string: data.picture)!)
        self.profileUsernameLabel.text = data.firstName + " " + data.lastName
        self.emailLabel.text = data.email
        self.phoneLabel.text = data.phone
        self.locationLabel.text = " " + data.location.city + ", " + data.location.country
        self.registeredDateLabel.text = "Joined since \((data.registerDate).prefix(10))"
    }
}

viewDidLoad() 方法中将 UserCell 注册到 tableView。

tableView.register(UserCell.self, forCellReuseIdentifier: "\(UserCell.self)")

我假设您有一个用户列表。所以声明一个 UserModel 的数组,如下所示

var users = [UserModel]()

numberOfRowsInSection()方法中returnusers数组的长度。

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

cellForRow() 方法中将单元格转换为 UserCell 并从中调用 setUser() 方法。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "\(UserCell.self)", for: indexPath) as? UserCell else {
        return UITableViewCell()
    }
    
    let user = users[indexPath.row]
    cell.setUser(with: user)
    return cell
}