[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