20/08/2018, 10:20

[Swift 4] Fix hiện tượng Cell bị chồng chéo và giúp tableView mượt mà hơn.

Xin chào các bạn. Tiếp theo phần trước mình đã đổ data từ API vào tableView. Nhưng còn tồn tại những vấn đề như sau. Lý thuyết là mỗi cell sẽ có một image. Nhưng các bạn nhìn hình bên dưới, mình cùng tìm nguyên nhân và cách chữa image của các cell bị đè lên nhau nhé. Nguyên nhân: Đầu ...

Xin chào các bạn. Tiếp theo phần trước mình đã đổ data từ API vào tableView.

Nhưng còn tồn tại những vấn đề như sau.

Lý thuyết là mỗi cell sẽ có một image. Nhưng các bạn nhìn hình bên dưới, mình cùng tìm nguyên nhân và cách chữa image của các cell bị đè lên nhau nhé.

Nguyên nhân:

Đầu tiên mình cùng review lại layout của cell trong file CustomCell:

//Hiện tại
func setup() {
        //imageSize: CGFloat = 30
        contentView.addSubview(cellImage)
        cellImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
        cellImage.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
        cellImage.heightAnchor.constraint(equalToConstant: imageSize).isActive = true
        cellImage.awidthAnchor.constraint(equalToConstant: imageSize).isActive = true
        
        contentView.addSubview(cellLabel)
        cellLabel.leadingAnchor.constraint(equalTo: cellImage.trailingAnchor, constant: 5).isActive = true
        cellLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5).isActive = true
        cellLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5).isActive = true
        cellLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5).isActive = true
    }

cellImage cố định height và awidth = 30.

Cạnh dưới (bottomAnchor) của cell (contentView là phần chứa view của cell) cách cạnh dưới của cellLabel là 5px.

Trong trường hợp này cạnh dưới của cell sẽ căn theo cạnh dưới của cellLabel chứ không liên quan gì đến cellImage.

Vì vậy những cellLabel nào có 1 dòng thì chiều cao của cell sẽ bị co hẹp đến mức các cellImage bị chồng lên nhau như hình trên.

Vấn đề cần giải quyết:

  • Trường hợp cellLabel chỉ có 1 dòng => mong muốn chiều cao tối thiểu của cell bằng chiều cao của cellImage.
  • cellLabel nhiều hơn 1 dòng => chiều cao của cell sẽ tự giãn (self-sizing).

Băt đầu sửa

Mình thêm bottomConstraint cho cellImage như sau.

//Hiện tại
func setup() {
        //imageSize: CGFloat = 30
        contentView.addSubview(cellImage)
        cellImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
        cellImage.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
        cellImage.heightAnchor.constraint(equalToConstant: imageSize).isActive = true
        cellImage.awidthAnchor.constraint(equalToConstant: imageSize).isActive = true
        cellImage.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
        
        contentView.addSubview(cellLabel)
        cellLabel.leadingAnchor.constraint(equalTo: cellImage.trailingAnchor, constant: 5).isActive = true
        cellLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5).isActive = true
        cellLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5).isActive = true
        cellLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5).isActive = true
    }

KẾT QUẢ cellImage không bị chồng lên nhau nữa rồi nè.

Nhưng lại gặp vấn đề nữa là text trong cellLabel không hiển thị hết (dull).

Lại sửa tiếp

Các bạn để ý đoạn code này nhé.

        cellImage.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
        và
        cellLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5).isActive = true

Cạnh dưới của contentView được constraint với cả cạnh dưới của cellImage và cellLabel.

Vì mình muốn chiều cao của cell giãn ra theo độ dài của cellLabel nên mình sẽ break cellImage.bottomAnchor.constraint bằng cách set độ ưu tiên của cellImage.bottomAnchor.constraint thấp hơn cellLabel.bottomAnchor.constraint như sau.

    //Khai báo constraint
    var imageBottom = NSLayoutConstraint()
    
    func setup() {
        contentView.addSubview(cellImage)
        cellImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
        cellImage.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
        cellImage.awidthAnchor.constraint(equalToConstant: imageSize).isActive = true
        cellImage.heightAnchor.constraint(equalToConstant: imageSize).isActive = true
        
        //gán constraint khai báo bên trên cho cellImage.bottomAnchor
        imageBottom = cellImage.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
        //set độ ưu tiên (priority) thấp hơn 1000
        //Vì độ ưu tiên mặc định = 1000
        imageBottom.priority = UILayoutPriority(rawValue: 750)
        imageBottom.isActive = true
        
        contentView.addSubview(cellLabel)
        cellLabel.leadingAnchor.constraint(equalTo: cellImage.trailingAnchor, constant: 5).isActive = true
        cellLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5).isActive = true
        cellLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5).isActive = true
        cellLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5).isActive = true
    }

KẾT QUẢ

Mọi thứ đều như mong muốn. Image không bị chồng nhau như lúc đầu nữa             </div>
            
            <div class=

0