2009-05-17 30 views
10

Tôi có chế độ xem tùy chỉnh trong ô bảng tùy chỉnh. Mỗi lần một thuộc tính cụ thể trên chế độ xem tùy chỉnh được thay đổi, tôi gọi số [self setNeedsDisplay] sẽ vẽ lại chế độ xem theo số - (void)drawRect:(CGRect)rect. Thuộc tính đó được đặt trong chế độ xem bảng của tableView:cellForRowAtIndexPath: của đại biểu. Nhưng khi chế độ xem bảng lớn hơn màn hình và các ô phải được sử dụng lại, drawRect không được gọi mỗi lần setNeedsDisplay là. Đặc biệt là khi tôi lướt nhanh bàn. Cuộn chậm hoạt động tốt. Điều này dẫn đến thông tin trong các ô đầu tiên và cuối cùng thường không chính xác.setNeedsDisplay không phải lúc nào cũng gọi drawRect

Trong nhật ký tôi có thể thấy rằng thông thường, đối với mỗi cuộc gọi đến setNeedsDisplay có một cuộc gọi đến drawRect, nhưng khi tôi di chuyển xem bảng một cách nhanh chóng có những cuộc gọi hơn để setNeedsDisplay hơn drawRect. Chắc chắn phải có một tỷ lệ một-một ở đây.

Tôi sử dụng cùng một chế độ xem tùy chỉnh trong UIView bình thường và nó vẽ lại hoàn hảo mỗi khi tôi gọi setNeedsDisplay. Sự cố có vẻ như bị cô lập với các chế độ xem bảng và sử dụng lại các ô.

Có ai biết điều gì đang xảy ra ở đây không? Có cách nào khác để buộc chế độ xem tùy chỉnh tự vẽ lại không?

Trả lời

13

Tôi đã gặp khó khăn với vấn đề này trong gần một tuần trước khi tôi phát hiện sự cố. Đây là, và tôi không đùa:

Con trỏ đến chế độ xem tùy chỉnh này được xác định trong tệp .m thay vì tệp .h, biến nó thành biến lớp thay vì biến mẫu.

Và có, tôi rất, rất xấu hổ.

1

Bạn nên gọi số [_table_ reloadData] để vẽ lại bảng. Không phải là [_table_cell_ setNeedsDsiplay]

+0

Tôi không vẽ lại bảng. Chỉ là chế độ xem tùy chỉnh. – kareman

+1

reloadData calls setNeedsHiển thị cho bạn vào đúng thời điểm. Bạn dường như đang chiến đấu với khung. Hãy để khung công tác quyết định cái nào cần cập nhật và chỉ triển khai tableView: cellForRowAtIndexPath: – amattn

+4

reloadData làm cho tất cả các ô của bảng bị hủy, nguồn dữ liệu được truy vấn lại và các ô hiển thị được tái tạo. Đó là nhiều hơn là cần thiết để chỉ làm mới một tế bào duy nhất. – rpetrich

0

Có vẻ như có hai trường hợp mà chế độ xem được làm mới: nếu giá trị nội bộ thay đổi (và bạn gọi [self setNeedsDisplay] để buộc cập nhật) và cũng có thể xem bảng yêu cầu một ô được vẽ hay không). Bạn không vẽ lại rõ ràng chế độ xem tùy chỉnh đó trong tình huống đó.

Theo các tài liệu:

Quan điểm của bảng đại biểu trong tableView: cellForRowAtIndexPath: nên luôn reset tất cả nội dung khi sử dụng lại một tế bào.

Nếu chế độ xem bảng là ô tái chế, nó sẽ đưa lại một ô có giá trị cũ vẫn còn tại chỗ. Tùy thuộc vào bạn để đảm bảo nội dung được cập nhật. Tùy thuộc vào cách bạn đã thiết lập ô bảng tùy chỉnh của mình, bạn có thể phải làm nhiều hơn để đảm bảo rằng chế độ xem đang tăng lên nhưng điều đơn giản nhất là trong trình xử lý ô tùy chỉnh bảng để thực hiện cuộc gọi đến [myCustomView setNeedsDisplay].

+0

Đó là những gì tôi đang làm. Trong tableView: cellForRowAtIndexPath: Tôi thay đổi dữ liệu cơ bản cho chế độ xem tùy chỉnh và gọi setNeedsDisplay trên đó. Trong nhật ký, tôi có thể thấy rằng thông thường, đối với mọi cuộc gọi đến setNeedsDisplay, có một cuộc gọi đến drawRect, nhưng khi tôi cuộn chế độ xem bảng một cách nhanh chóng, có nhiều lệnh gọi setNeedsDisplay hơn drawRect. Chắc chắn phải có một tỷ lệ một-một ở đây. – kareman

+1

Thử di chuyển ô ra khỏi chế độ xem và quay lại để xem thay đổi có hiệu lực hay không. Tôi vừa nhớ rằng tôi đã gửi một bản báo cáo về vấn đề chính xác này (Bug # 6022064: UITableViews và cập nhật chế độ xem phụ kiện) vào năm ngoái. Họ trả lời rằng họ không thể tái tạo lỗi. Trong trường hợp của tôi, một navcontroller được gọi, nó sẽ thay đổi màu sắc cho accessoryView và setNeedsDisplay sẽ được gọi, nhưng khi bạn quay trở lại, nó sẽ không làm mới. Di chuyển off-table & back sẽ hiển thị màu phù hợp. Nếu nó hoạt động giống nhau và bạn có thể cô lập nó, có thể bạn có thể gửi và loại bỏ lỗi. – Ramin

6

setNeedsDisplay sẽ chỉ gọi drawRect: nếu chế độ xem hiển thị, nếu không nó sẽ làm mất hiệu lực lớp của chế độ xem và drawRect: sẽ được gọi khi hiển thị.

Khi cuộn qua chế độ xem bảng, chế độ xem bảng sẽ yêu cầu các ô có hy vọng thêm chúng vào chế độ xem. Nếu di chuyển đủ nhanh, một số ô sẽ mất quá nhiều thời gian để chuẩn bị và vào thời điểm chúng sẵn sàng, vị trí chúng sẽ được định vị là tắt màn hình. Trong những trường hợp này, chế độ xem bảng loại bỏ chúng thay vì thêm chúng vào chế độ xem cuộn (và do đó drawRect: sẽ không được gọi)

+1

Ngoài ra, setNeedsDisplay chỉ ảnh hưởng đến chế độ xem được gọi. Nếu cần thiết, bất kỳ bản xem phụ nào sẽ bị vô hiệu độc lập – rpetrich

+0

Âm thanh hợp lý cho các bảng lớn, nhưng bảng của tôi chỉ có 10 hàng, 8 hàng trong số đó có thể nhìn thấy cùng một lúc. Nó sẽ không chỉ áp dụng nếu một tế bào đi từ bên dưới bàn lên trên nó trước khi nó có thể được vẽ lại? – kareman

+0

Vâng, điều đó sẽ chỉ áp dụng cho các bảng lớn. Trong bảng của bạn, tất cả 8 hàng hiển thị sẽ nhận được drawRect: ... nếu không đó có thể là lỗi ở đâu đó. Bạn có thể gửi mã của bạn (hoặc một phiên bản đơn giản mà vẫn có lỗi)? – rpetrich

Các vấn đề liên quan