2014-10-20 25 views
23

Tôi đã sauLàm thế nào để tham khảo bộ điều khiển từ một lớp UITableViewCell trong Swift

  1. ViewController
  2. tableView
  3. CustomCell

tôi đã sử dụng một NIB (một tập tin .xib) cho ô, sử dụng lớp CustomCell. Lớp tế bào tùy chỉnh này xử lý IBAction cho một số liên lạc trên nút của ô. Tôi muốn tham khảo ViewController và một số biến của nó bên trong nó. Làm thế nào tôi phải làm điều đó (truy cập ViewController)?

Cảm ơn!

Trả lời

31

Tôi sẽ không tạo loại phụ thuộc này giữa ô và bộ điều khiển khung - điều đó làm cho kiến ​​trúc phức tạp hơn và không thể tái sử dụng được.

tôi đề nghị bạn sử dụng các mô hình đoàn, trong đó có thể âm thanh một chút phức tạp - mặc dù bạn đã sử dụng (UITableViewDelegate là một ví dụ điển hình):

  • tạo ra một giao thức MyCellProtocol với một phương pháp didTapCell, chấp nhận một UITableViewCell và/hoặc một số dữ liệu tùy chỉnh bạn muốn vượt qua với bộ điều khiển xem
  • tạo ra một tài sản public delegate trong tế bào tùy chỉnh của bạn: var cellDelegate: MyCellProtocol?
  • trong xử lý didTapXXX hoặc.210 tế bào của bạn, hãy gọi self.cellDelegate?.didTapCell(), đi qua các thông số dự kiến ​​
  • trong điều khiển điểm của bạn, thực hiện các MyCellProtocol
  • trong cellForRowAtIndexPath của bộ điều khiển tầm nhìn của bạn, khi tạo/dequeuing tế bào, thiết lập thuộc tính cellDelegate của nó để self

Tại thời điểm này, khi một vòi nước được thực hiện trong tế bào của bạn, phương pháp didTapCell của bộ điều khiển xem được gọi, và từ đó bạn có thể làm bất cứ điều gì bạn cần để đạt được.

Điểm mấu chốt là: thay vì làm cho ô xử lý thao tác chạm/chọn ô, hãy thông báo cho bộ điều khiển chế độ xem và để cho nó thực hiện công việc.

+0

Dấu đầu dòng thứ hai ở trên dường như dành cho Mục tiêu-C. Trong một nhanh chóng có thể làm điều này: cho đại biểu: ClasThatImplementsProtocol – zeeple

+0

nhờ @ user1639164, mã cố định – Antonio

+1

Điều này có thể làm việc. Nhưng khi đóng gói dataSource vào một lớp khác, như bạn nên (không đặt DS vào bộ điều khiển), bạn cần tìm một cách khác để kết nối các ô và bộ điều khiển. Một điều bạn có thể làm là sử dụng phương thức tableView delegate willDisplayCell để gán tableview làm đại biểu cho ô đó. Sau đó bạn cần phải hủy liên kết chúng trong PrepareForReuse và dealloc hoặc deinit tùy thuộc vào ngôn ngữ bạn đang sử dụng. Thông báo cũng không phải là giải pháp lý tưởng nếu có nhiều bộ điều khiển hoạt động mà nghe cùng một thông báo. –

7

Tôi không nghĩ bạn nên làm điều đó và có thể bạn đang làm điều gì đó sai, nhưng nếu bạn thực sự cần nó thì chỉ cần có một tài sản trong lớp học CustomCell của bạn.

var viewController : UIViewController 

sau đó khi bạn tạo ra các tế bào trong cellForRowAtIndexPath thiết lập thuộc tính

cell.viewController = self 

sau đó bạn có thể dễ dàng truy cập vào bộ điều khiển nhìn từ bên trong mã di động:

self.viewController.doSomething() 

Nhưng một lần nữa, theo ý kiến ​​của tôi, bạn nên thiết kế lại mã của mình. Các tế bào không nên quan tâm đến bộ điều khiển. Nó sẽ chỉ quan tâm đến việc hiển thị chính nó và không có gì khác

+0

> "Các tế bào không nên quan tâm đến bộ điều khiển. Nó nên chỉ quan tâm đến hiển thị bản thân và không có gì khác" Liệu nó có nghĩa rằng nó cũng là xấu thực hành để thêm các nút trong một tế bào tùy chỉnh nếu hành động của nút sẽ truy cập hoặc thay đổi một số thuộc tính mô hình? Bởi vì trong trường hợp đó, mô hình có thể truy cập chỉ từ bộ điều khiển vì nó là nguồn của khung nhìn bảng ... –

+3

nó không phải là tất nhiên. một thực hành tồi tệ là phải có mã để xử lý rất nhiều công cụ của mô hình trong hành động của nút. một thực hành tốt trong trường hợp này là chỉ có một dòng mã trong hành động của nút. dòng sẽ đăng thông báo hoặc gọi phương thức đại biểu. và sau đó bộ điều khiển sẽ phản ứng trên cuộc gọi này hoặc thông báo này và chạy tất cả các mã cần thiết. điều khiển, không phải là ô. Tôi hy vọng bạn hiểu những gì tôi đang nói về –

+2

trong hầu hết các khung giao diện người dùng của nó rất phổ biến để truy cập vào vùng chứa của đối tượng, ví dụ trong ActionScript, bạn có thể gọi cha mẹ bằng this.parent và từ kinh nghiệm của tôi bằng ngôn ngữ Apple có vẻ như Apple không đủ kinh nghiệm với ngôn ngữ lập trình trực quan, vì vậy tôi đoán giải pháp này là rất chấp nhận được và thông minh và tôi sẽ cung cấp cho nó +1 –

0

Đọc các ý kiến ​​khác về thực sự muốn sử dụng một cách tiếp cận thay thế trước khi cố gắng này, nhưng sử dụng phần mở rộng này sẽ cho phép bạn để có được dataSourcedelegate cả trong số đó nên là UITableViewController

extension UITableViewCell { 
    var tableView:UITableView? { 
     get { 
      for var view = self.superview ; view != nil ; view = view!.superview { 
       if view! is UITableView { 
        return (view! as UITableView) 
       } 
      } 
      return nil 
     } 
    } 

    var tableViewDataSource:UITableViewDataSource? { 
     get { 
      return self.tableView?.dataSource 
     } 
    } 

    var tableViewDelegate:UITableViewDelegate? { 
     get { 
      return self.tableView?.delegate 
     } 
    } 
} 
11
extension UIView { 
    var parentViewController: UIViewController? { 
     var parentResponder: UIResponder? = self 
     while parentResponder != nil { 
      parentResponder = parentResponder!.nextResponder() 
      if let viewController = parentResponder as? UIViewController { 
       return viewController 
      } 
     } 
     return nil 
    } 
} 

Bên trong ô của bạn

if let myViewController = parentViewController as? MyViewController { 
    print(myViewController.title) 
} 
+0

Tôi muốn thực hiện một phân đoạn từ một uicollectionviewcell lồng trong một uitableviewcell và điều này làm việc hoàn hảo! . Cảm ơn. – webjunkie

+0

Đã làm việc trong mẫu Dự án chi tiết chính. Cảm ơn bạn. –

+1

trong Swift 4, '.nextResponder()' được thay đổi thành '.next' – troligtvis

1

Cách tốt nhất là triển khai Đoàn. Đại biểu của bạn sẽ thông báo cho bộ điều khiển xem về nút bấm. Và, lần lượt bộ điều khiển xem của bạn (người đang tuân thủ giao thức cho đại biểu trên) sẽ xử lý tác vụ mà bạn muốn thực hiện trên sự kiện nhấp chuột. (Hướng dẫn mô hình ủy quyền có sẵn trực tuyến. Bạn có thể xem qua chúng nếu bạn muốn biết cách thực hiện ủy quyền).

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