Table 视图设计重叠

Table View Design overlapping

我是 swift 的新手。我想在 table 视图单元格中显示带有图像视图的记录。我已经用 leadingAnchor 、 trailingAnchor 、 widthAnchor 、 heightAnchor 和 content view 定义了 属性 。但是当我 运行 应用程序与视图重叠时。

这是单元格中的代码。

import UIKit

class PeopleCell: UITableViewCell {

    
    static let identifier = "PeopleCell"
    
    let containerView:UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.clipsToBounds = true // this will make sure its children do not go out of the boundary
        return view
    }()
    
    let profileImageView:UIImageView = {
        let img = UIImageView()
        img.contentMode = .scaleAspectFill // image will never be strecthed vertially or horizontally
        img.translatesAutoresizingMaskIntoConstraints = false // enable autolayout
        img.layer.cornerRadius = 35
        img.clipsToBounds = true
        return img
    }()
    
    let firstnameTitleLabel:UILabel = {
        let label = UILabel()
        label.font = UIFont.boldSystemFont(ofSize: 20)
        label.textColor = .black
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let lastnameTitleLabel:UILabel = {
        let label = UILabel()
        label.font = UIFont.boldSystemFont(ofSize: 14)
        label.textColor =  .white
        label.backgroundColor = #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1)
        label.layer.cornerRadius = 5
        label.clipsToBounds = true
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        self.contentView.addSubview(profileImageView)
        containerView.addSubview(firstnameTitleLabel)
        containerView.addSubview(lastnameTitleLabel)
        self.contentView.addSubview(containerView)
         
        profileImageView.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
        profileImageView.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor, constant:10).isActive = true
        profileImageView.widthAnchor.constraint(equalToConstant:70).isActive = true
        profileImageView.heightAnchor.constraint(equalToConstant:70).isActive = true
        
        containerView.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
        containerView.leadingAnchor.constraint(equalTo:self.profileImageView.trailingAnchor, constant:10).isActive = true
        containerView.trailingAnchor.constraint(equalTo:self.contentView.trailingAnchor, constant:-10).isActive = true
        containerView.heightAnchor.constraint(equalToConstant:40).isActive = true
        
        firstnameTitleLabel.topAnchor.constraint(equalTo:self.containerView.topAnchor).isActive = true
        firstnameTitleLabel.leadingAnchor.constraint(equalTo:self.containerView.leadingAnchor).isActive = true
        firstnameTitleLabel.trailingAnchor.constraint(equalTo:self.containerView.trailingAnchor).isActive = true
        
        lastnameTitleLabel.topAnchor.constraint(equalTo:self.firstnameTitleLabel.bottomAnchor).isActive = true
        lastnameTitleLabel.leadingAnchor.constraint(equalTo:self.containerView.leadingAnchor).isActive = true
        lastnameTitleLabel.topAnchor.constraint(equalTo:self.firstnameTitleLabel.bottomAnchor).isActive = true
        lastnameTitleLabel.leadingAnchor.constraint(equalTo:self.containerView.leadingAnchor).isActive = true
        
        
    }
   
    
   required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func configureCell(firstName: String, lastName: String) {
        firstnameTitleLabel.text = "Firstname :\(firstName)"
        lastnameTitleLabel.text = "Lastname : \(lastName)"
        
        }
        
    
    func configureImageCell(row: Int, viewModel: ViewModel) {
        
        profileImageView.image = nil
        
        viewModel
            .downloadImage(row: row) { [weak self] data in
                let image = UIImage(data: data)
                self?.profileImageView.image = image
            }
    }
}

这是视图控制器代码。

import UIKit
import Combine

class PeopleViewController: UIViewController {
    
    var coordinator: PeopleBaseCoordinator?
    
    
    init(coordinator: PeopleBaseCoordinator) {
        super.init(nibName: nil, bundle: nil)
        self.coordinator = coordinator
        title = "People"
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private let viewModel = ViewModel()
    private var subscribers = Set<AnyCancellable>()
    
    
    var activityIndicator = UIActivityIndicatorView(style: .medium)
    
    
    private lazy var tableView: UITableView = {
        let tableview = UITableView()
        tableview.translatesAutoresizingMaskIntoConstraints = false
        tableview.dataSource = self
        tableview.prefetchDataSource = self
        tableview.showsVerticalScrollIndicator = false
        tableview.register(PeopleCell.self, forCellReuseIdentifier: PeopleCell.identifier)
        
        return tableview
    }()
    
   

    override func viewDidLoad() {
        super.viewDidLoad()
        
        activityIndicator.startAnimating()
        setUpUI()
       
        setUpBinding()
        self.activityIndicator.stopAnimating()
     
        // Do any additional setup after loading the view.
    }
    
    
    private func setUpUI() {
        view.backgroundColor = .white
        
        title = "People List "
        
      
        view.addSubview(tableView)
   
        tableView.topAnchor.constraint(equalTo:view.safeAreaLayoutGuide.topAnchor).isActive = true
        tableView.leftAnchor.constraint(equalTo:view.safeAreaLayoutGuide.leftAnchor).isActive = true
        tableView.rightAnchor.constraint(equalTo:view.safeAreaLayoutGuide.rightAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
       
        
        
        // Creating constrain for Indecator
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(activityIndicator)
        activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
          
    }
    
    private func setUpBinding() {
        viewModel
            .$peoples
            .receive(on : RunLoop.main)
            .sink { [weak self ] _ in
                self?.tableView.reloadData()
            }
            .store(in: &subscribers)
        viewModel.getPeople()
        
    }

}
extension PeopleViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.peoples.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: PeopleCell.identifier, for: indexPath) as? PeopleCell
        else { return UITableViewCell() }
        
        
        let row = indexPath.row
        let people = viewModel.peoples[row]
        cell.configureCell(firstName: people.firstName, lastName: people.lastName)
    
        cell.configureImageCell(row: row, viewModel: viewModel)
        
        return cell
        
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }
}
extension PeopleViewController: UITableViewDataSourcePrefetching {
    
    func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
        viewModel.getPeople()
    }
    
}

这是结果。

这很棘手,因为假设您的表格视图高度为 100,您的约束似乎很好,但屏幕截图表格视图单元格似乎比 100 短一点。我们假设单元格高度为 100 是正确的。

我建议您尝试在 override func layoutSubViews() 中配置 imageView(和其他视图),这是一个在 contentView 的绑定更改时呈现的函数。还应注意,更好的做法是 imageSize 是相对于 cell/contentView 的帧而不是硬编码值。

所以它应该看起来像

import UIKit

class PeopleCell: UITableViewCell {

    let profileImageView:UIImageView = {
        let img = UIImageView()
        return img
    }()

    override func layoutSubviews() {
        super.layoutSubviews()

profileImageView.translatesAutoresizingMaskIntoConstraints = false profileImageView.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
       profileImageView.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor, constant:10).isActive = true
      profileImageView.widthAnchor.constraint(equalToConstant:self.frame.width * 0.7).isActive = true
      profileImageView.heightAnchor.constraint(equalToConstant:self.frame.width * 0.7).isActive = true

//You may want to try with other type of contentMode such as aspectFit, etc
profileImageView.contentMode = .scaleAspectFill
profileImageView.layer.cornerRadius = self.frame.width / 2
profileImageView.clipsToBounds = true
        
}

//If above doesn't work, you may want to look into the imageConfiguration function you made and ensure that contentMode is applied properly. 

    func configureImageCell(row: Int, viewModel: ViewModel) {
        
        profileImageView.image = nil
        
        viewModel
            .downloadImage(row: row) { [weak self] data in
                let image = UIImage(data: data)
                self?.profileImageView.image = image
                self?.profileImageView.contentMode = .scaleAspectFill
            }
    }

如果以上所有代码都不起作用,请尝试使用断点或 Xcode 中的 ViewHierarchy 来查找 profileImageView 大小值。检查图像或单元格本身的高度,它们应该足以让您找到解决问题的线索。

祝一切顺利。