Để biết khi nào chế độ xem bảng hoàn tất tải nội dung của nó, trước tiên chúng ta cần có hiểu biết cơ bản về cách các chế độ xem được hiển thị trên màn hình.
Trong vòng đời của một ứng dụng, có 4 thời điểm chính:
- Ứng dụng nhận được một sự kiện (chạm, hẹn giờ, gửi đi, v.v.)
- Ứng dụng xử lý sự kiện (nó sửa đổi một ràng buộc, bắt đầu một hình động, thay đổi nền, v.v.)
- Ứng dụng tính toán phân cấp chế độ xem mới
- Ứng dụng hiển thị phân cấp chế độ xem và hiển thị nó
2 và 3 lần hoàn toàn tách biệt. Tại sao ? Vì lý do hiệu suất, chúng tôi không muốn thực hiện tất cả các tính toán của thời điểm 3 mỗi lần thực hiện sửa đổi.
Vì vậy, tôi nghĩ rằng bạn đang phải đối mặt với một trường hợp như thế này:
tableView.reloadData()
tableView.visibleCells.count // wrong count oO
Có chuyện gì ở đây vậy?
Giống như bất kỳ chế độ xem nào, chế độ xem bảng tải lại nội dung của nó một cách lười biếng. Trên thực tế, nếu bạn gọi reloadData
nhiều lần, nó sẽ không tạo ra vấn đề về hiệu suất. Chế độ xem bảng chỉ tính toán lại kích thước nội dung của nó dựa trên việc triển khai ủy nhiệm của nó và đợi thời điểm 3 để tải các ô của nó. Thời gian này được gọi là vượt qua bố trí.
Được rồi, làm thế nào để vào được pass layout?
Trong quá trình bố trí, ứng dụng sẽ tính toán tất cả các khung của hệ thống phân cấp chế độ xem. Để tham gia, bạn có thể ghi đè các phương thức chuyên dụng layoutSubviews
, updateLayoutConstraints
vv trong một UIView
và các phương thức tương đương trong lớp con của trình điều khiển xem.
Đó chính xác là những gì một chế độ xem bảng làm. Nó ghi đè layoutSubviews
và dựa trên việc triển khai ủy nhiệm của bạn thêm hoặc xóa các ô. Nó gọi cellForRow
ngay trước khi thêm và đặt một ô mới, willDisplay
ngay sau đó. Nếu bạn đã gọi reloadData
hoặc chỉ thêm chế độ xem bảng vào cấu trúc phân cấp, chế độ xem bảng sẽ thêm nhiều ô cần thiết để điền vào khung của nó tại thời điểm quan trọng này.
Được rồi, nhưng bây giờ, làm thế nào để biết khi nào một chế độ xem bảng đã tải lại nội dung của nó?
Bây giờ chúng ta có thể viết lại câu hỏi này: làm thế nào để biết khi nào một chế độ xem bảng đã hoàn thành việc đưa ra các bản xem xét của nó?
• Cách dễ nhất là vào bố cục của chế độ xem bảng:
class MyTableView: UITableView {
func layoutSubviews() {
super.layoutSubviews()
// the displayed cells are loaded
}
}
Lưu ý rằng phương thức này được gọi nhiều lần trong vòng đời của chế độ xem bảng. Do cuộn và hành vi dequeue của chế độ xem bảng, các ô được sửa đổi, loại bỏ và thêm thường xuyên. Nhưng nó hoạt động, ngay sau khi super.layoutSubviews()
, các tế bào được tải. Giải pháp này tương đương với việc chờ willDisplay
sự kiện của đường dẫn chỉ mục cuối cùng. Sự kiện này được gọi trong quá trình thực hiện layoutSubviews
chế độ xem bảng cho mỗi ô được thêm vào.
• Một cách khác là được gọi khi ứng dụng hoàn thành việc vượt qua bố cục.
Như được mô tả trong tài liệu , bạn có thể sử dụng một tùy chọn UIView.animate(withDuration:completion)
:
tableView.reloadData()
UIView.animate(withDuration: 0) {
// layout done
}
Giải pháp này hoạt động nhưng màn hình sẽ làm mới một lần giữa thời gian bố trí được thực hiện và thời gian khối được gọi. Điều này tương đương với DispatchMain.async
giải pháp nhưng được chỉ định.
• Ngoài ra, tôi muốn buộc bố cục của chế độ xem bảng
Có một phương pháp chuyên dụng để buộc bất kỳ chế độ xem nào tính toán ngay các khung nhìn phụ của nó layoutIfNeeded
:
tableView.reloadData()
table.layoutIfNeeded()
// layout done
Tuy nhiên, hãy cẩn thận, làm như vậy sẽ loại bỏ tải lười biếng được sử dụng bởi hệ thống. Gọi các phương thức đó nhiều lần có thể tạo ra các vấn đề hiệu suất. Đảm bảo rằng chúng sẽ không được gọi trước khi khung của chế độ xem bảng được tính, nếu không, chế độ xem bảng sẽ được tải lại và bạn sẽ không được thông báo.
Tôi nghĩ rằng không có giải pháp hoàn hảo. Các lớp học phân lớp có thể dẫn đến các trubles. Một đường chuyền bố trí bắt đầu từ trên xuống và đi xuống dưới để không dễ dàng nhận được thông báo khi tất cả bố cục được thực hiện. Và layoutIfNeeded()
có thể tạo ra các vấn đề về hiệu suất, v.v. Nhưng biết những lựa chọn đó, bạn sẽ có thể suy nghĩ ở một giải pháp thay thế phù hợp với nhu cầu của bạn.