2012-09-25 16 views
39

Tôi thấy điều này được sử dụng trong một video WWDC nhưng chỉ rất ngắn gọn. Họ đã không đi vào làm thế nào để tạo ra các tập tin xib thực tế.UITableView registerNib: forCellReuseIdentifier:

Tôi có một lớp con UITableViewCell có tên là MyCustomCell. Trong này tôi có một số thuộc tính UILabels, UIImageViews, vv ... tất cả được thiết lập như IBOutlets.

Bây giờ, trong file xib của tôi ...

để tôi thiết gì là chủ sở hữu của tập tin? Tôi tham khảo lớp MyCustomCell của tôi ở đâu là chủ sở hữu của tệp này?

Khi tôi đã đặt chủ sở hữu của tệp làm cách nào để liên kết nó với chế độ xem gốc của xib?

Tôi đã thử một vài cài đặt nhưng tôi vẫn gặp phải lỗi khi sử dụng.

Oh, mã Tôi đang sử dụng để đăng ký nó là ...

self.cellNib = [UINib nibWithNibName:@"MyCustomCell" bundle:nil]; 
[self.tableView registerNib:self.cellNib forCellReuseIdentifier:@"CustomCell"]; 

Cảm ơn

+0

Xin chào, @Fogmeister Tôi có nhiều nghi ngờ, cách bạn đặt câu hỏi. Câu trả lời là chính xác khi họ đã hiểu chính xác. Trong tiêu đề câu hỏi bạn đề cập về "đăng ký nib", và trong cơ thể bạn ae đề cập về làm thế nào để liên kết các tập tin XIB với lớp Cell và ra cho phép. –

+0

Tôi xin lỗi, tôi đang vội vàng, nhưng câu hỏi của tôi là chúng ta cần phải đăng ký di động, trong khi chúng tôi đang sử dụng ô tùy chỉnh, với xib. Và tôi làm giống như câu trả lời được đánh dấu của bạn. Tôi đang sử dụng bảng phân cảnh. –

+0

Tôi ra ngoài, chủ yếu là thấy ngày mai khi tôi đi làm. Cảm ơn bạn. Xin vui lòng. –

Trả lời

44

Thông thường bạn không cần phải bận tâm về chủ sở hữu của tập tin trong trường hợp đó, bởi vì khi tableView khởi tạo ô từ số được cung cấp/liên kết UINib cùng với reuseIdentifier. Nó sẽ tải tất cả các đối tượng cấp cao nhất của ngòi bút, và chỉ sử dụng đối tượng cấp cao nhất đầu tiên của lớp UITableViewCell (hoặc có thể chỉ là đối tượng cấp cao nhất bất kể lớp nào? có UITableViewCell của bạn trong XIB của bạn anyway - mà không tính File's OwnerFirst Responder mà chỉ là "proxy").

Thực tế, tableView sẽ cố gắng xóa bỏ một ô và nếu không tìm thấy ô có thể dùng lại, nó sẽ tạo một ô mới bằng cách sử dụng UINib mà bạn đã cung cấp. Nó sẽ là một cái gì đó tương tự này:

NSArray* topLevelObjects = [self.cellNib instantiateWithOwner:nil options:0]; 
cell = [topLevelObjects objectAtIndex:0]; 

(Đó là tất nhiên một phiên bản đơn giản chỉ là để hiển thị các ý tưởng, tôi không biết nếu nó thực sự kêu gọi những dòng này chính xác, nhưng nó phải là khá chặt chẽ)

vì vậy các File's Owner không được sử dụng trong trường hợp đặc biệt này, và bạn chỉ cần đặt một tùy chỉnh đơn giản UITableViewCell như chỉ cấp đối tượng trên cùng của tập tin XIB bạn bên cạnh File's Owner và kiên hiện First Responder (đó, một lần nữa, chỉ là "proxy"/"Tham chiếu đối tượng bên ngoài" và sẽ không được khởi tạo và sẽ không là một phần của các đối tượng cấp cao nhất được trả về bởi instantiateWithOwner:options:).


Nếu nó vẫn không hoạt động:

  • Đảm bảo rằng bạn một cách chính xác đầy reuseIdentifier của UITableViewCell của bạn trong IB (trong cửa sổ Object Inspector ở bên phải khi bạn chọn di động của bạn trong IB) và sử dụng cùng một giá trị chính xác cho thuộc tính reuseIdentifier này trong IB mà bạn sử dụng trong mã số.
  • Nếu vẫn không có may mắn, vui lòng cung cấp thêm thông tin, đặc biệt là loại lỗi, thông báo tường trình hoặc ngoại lệ bạn có.
+3

Cảm ơn! Tôi đã rời khỏi đầu xem như là một UIView đó là lý do tại sao nó không hoạt động. Một khi tôi đã xóa và thêm một UItableViewCell như là xem đầu nó làm việc tốt. Cảm ơn. – Fogmeister

+3

Tôi chỉ muốn bình luận lại. Điều này đã được như vậy không thể tin được hữu ích! Tôi đã refactored một địa ngục của rất nhiều giao diện người dùng ra khỏi storyboard của tôi và trong để tách các tập tin XIB đã giảm đáng kể phức tạp và bảo trì các ứng dụng tôi đang làm việc trên! Cảm ơn một lần nữa: D – Fogmeister

+0

Vui mừng đã giúp;) – AliSoftware

9

Tôi đã tìm thấy mã được đưa ra trong câu hỏi là tốt, nhưng bạn không thể tham chiếu đến self.tableView trong phương thức init nếu bạn đang sử dụng bảng phân cảnh. Có một số discussion về nó trong một câu hỏi khác.

Vì vậy, dòng đầu tiên đi trong init:

self.cellNib = [UINib nibWithNibName:@"MyCustomCell" bundle:nil];

Nhưng dòng này nên đi trong viewDidLoad hoặc tương tự:

[self.tableView registerNib:self.cellNib forCellReuseIdentifier:@"CustomCell"];

Đó sửa lỗi bí ẩn của tôi, ví dụ "*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle <Foo.app> (loaded)' with name 'Ogf-Sj-1ej-view-bBf-Ti-Dda''"

Và, vâng, tôi đang làm điều gì đó rất giống với việc lấy đồ vật ra khỏi Bảng phân cảnh và đặt chúng vào xib để sử dụng lại trên các bộ điều khiển chế độ xem!

+0

Ach, không phải là một thông báo lỗi rất rõ ràng là nó! – fatuhoku

+0

@fatuhoku Chào mừng bạn đến với thế giới của lỗi xcode/objectivec. Không phải là những điểm ngắt trong phương pháp chính hữu ích sao? – csga5000

3

Ngoài trả lời từ "AliSoftware" Lưu ý điều rõ ràng nhất là ra ở đây là UITableViewCell phải là Root Xem * TRÊN * ngay cả những UIView. Theo mặc định khi tôi chọn một tập tin IB mới nó tạo ra một UIView. Vì vậy, xóa các UIView giúp. Cảm ơn.

PS: Tôi muốn nhận xét về câu trả lời đó nhưng vì một lý do lạ tôi không thể nhận xét, chỉ có thể trả lời. Đoán tôi cần một đánh giá nhất định.