ios 在单独的文件中设置UITableView数据源和委托- swift

hl0ma9xz  于 2022-12-24  发布在  iOS
关注(0)|答案(4)|浏览(138)

如果我想让相同的基本UITableView出现在两个不同的场景中,那么对两个表使用一个数据源和委托位置是否是一个好主意?
我想试试这个,但是当我在IB中选择表视图,并试图将行拖到UITableView文件的一个自定义类,甚至拖到另一个自定义视图控制器时,它都不会连接,似乎只能将当前的视图控制器做成表的数据源并委托(?)。
我想知道这是否至少与this question相似,但即使是,在swift中是如何做到的(也许有一种新的方法可以做到这一点)。

k2arahey

k2arahey1#

Swift 4.1.你可以创建一个单独的类,并从UITableViewDataSource和UITableViewDelegate类继承它。这里,我在DataSource类中实现UITableViewDataSource()方法。你还需要确认NSObject,这样我们就不必摆弄**@objc@class关键字,因为UITableViewDataSource是一个Objective-C协议**。

import Foundation
import UIKit

class DataSource: NSObject, UITableViewDataSource {
  var formData: [FormData]? = nil

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.formData?.count ?? 0
  }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
    let label = cell?.contentView.viewWithTag(100) as? UILabel
    let type = self.formData![indexPath.row]
    label?.text = type.placeHolder
    return cell!
  }
}

现在,我们将DataSource设置为UITableView。如果我们创建单独的类,那么我们必须将数据传递给DataSource类。

class ViewController: UIViewController {
    
      @IBOutlet weak var tblView: UITableView!
      var formData: [FormData]? = nil
      var dataSource = DataSource()
     
       override func viewDidLoad() {
          super.viewDidLoad()
          formData = FormData.array
          dataSource.formData = formData // Pass data to DataSource class
          tblView.dataSource = dataSource // Setting DataSource
      }
    }

类似地,你可以在单独的类中实现UITableViewDelegate。另一种分离DataSource和Delegate的方法是创建viewController的扩展。甚至你可以创建单独的类,在那里你只能为你的视图控制器定义扩展。在你定义扩展时,你不需要传递数据。

class ViewController: UIViewController {

  @IBOutlet weak var tblView: UITableView!
  var formData: [FormData]? = nil

  override func viewDidLoad() {
    super.viewDidLoad()
    formData = FormData.array
    tblView.dataSource = self
  }
}

extension ViewController:  UITableViewDataSource {
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.formData?.count ?? 0
  }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
    let label = cell?.contentView.viewWithTag(100) as? UILabel
    let type = self.formData![indexPath.row]
    label?.text = type.placeHolder
    label?.backgroundColor = UIColor.gray
    return cell!
  }
}
brqmpdu1

brqmpdu12#

下面的代码示例显示UITableView的不同Datasource和委托。

Swift代码

import UIKit

// MARK: Cell

class ItemCell: UITableViewCell{
    var label: UILabel!
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 20))
        label.textColor = .black
        label.backgroundColor = .yellow
        contentView.addSubview(label)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

// MARK: Main View Controller

class BlueViewController: UIViewController{

    var tableView: UITableView!
    var myDataSourse: MyTVDataSource!
    var myDelegate: MyTVDelegate!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .blue
        tableView = UITableView()
        myDataSourse = MyTVDataSource(tableView: tableView)
        myDelegate = MyTVDelegate()
        myDelegate.presentingController = self
        tableView.dataSource = myDataSourse
        tableView.delegate = myDelegate
        tableView.register(ItemCell.self, forCellReuseIdentifier: "Cell")

        self.view.addSubview(tableView)


        self.tableView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0),
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0)
            ])
    }
}
extension BlueViewController: BluePresenting{
    func currentSelected(_ indexPath: IndexPath) {
        print(indexPath)
    }

}

// MARK: TableViewDelegate

protocol BluePresenting: class {
    func currentSelected(_ indexPath: IndexPath)
}

class MyTVDelegate: NSObject,UITableViewDelegate{

   var presentingController: BluePresenting?

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            presentingController?.currentSelected(indexPath)
    }
}

// MARK: TableView DataSource

class MyTVDataSource: NSObject, UITableViewDataSource{
    private var tableView: UITableView
    private var items = ["Item 1","item 2","item 3","Item 4"]

    init(tableView: UITableView) {
        self.tableView = tableView
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count

    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = ItemCell(style: .default, reuseIdentifier: "Cell")
        cell.label.text = items[indexPath.row]

        return cell
    }

}
rlcwz9us

rlcwz9us3#

您可以实现自定义类对象,并实现该类的UITableViewDataSource方法。

@interface MyDataSource : NSObject <UITableViewDataSource>

//...

@end

然后,UITableView具有属性delegatedataSource。为这些属性分配正确的对象。

MyDataSource ds = ... ///< Initialize the dataSource object.
self.tableView.dataSource = ds; ///< Let ds be the dataSource of `self.tableView`
self.tableView.delegate = .... ///< Assign the delegate, generally it is `self`.
mpgws1up

mpgws1up4#

每个表视图都应该有自己的表视图控制器。这与模型视图控制器设计模式一致。
如果两个表中的数据相同,则可以使用一个公共类作为dataSource。

相关问题