在单独的文件中设置 UITableView 数据源和委托 - swift
Posted
技术标签:
【中文标题】在单独的文件中设置 UITableView 数据源和委托 - swift【英文标题】:Setting a UITableView data source and delegate in separate file - swift 【发布时间】:2016-02-29 06:30:05 【问题描述】:如果我想让相同的基本 UITableView 出现在两个不同的场景中,是否为两个表使用一个数据源和委托位置是个好主意?
我想试试这个,但是当我在 IB 中选择表格视图并尝试将线拖到 UITableView 文件的自定义类,甚至到另一个自定义视图控制器时,它不会连接。似乎只能将当前的 View Controller 变成表的数据源和委托(?)。
我想知道这是否至少类似于this question,但即使是,如何快速完成(也许有一种新方法可以做到这一点)。
【问题讨论】:
【参考方案1】:每个 Tableview 都应该有自己的 Tableview 控制器。这符合模型视图控制器设计模式。
如果两个表中的数据相同,则可以有一个公共类作为数据源。
【讨论】:
【参考方案2】:您可以实现自定义类对象,并为此类实现UITableViewDataSource
方法。
@interface MyDataSource : NSObject <UITableViewDataSource>
//...
@end
然后,UITableView
具有属性delegate
和dataSource
。
将正确的对象分配给这些属性。
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`.
【讨论】:
虽然这并不快,而且您没有提到创建 tableView 插座,但它已经足够清楚了。您真的需要 self.tableView.dataSource 还是 viewDIdLoad 中的 tableView.dataSource 足够? 我不知道怎么写swift。但我认为它们是相同的。 自定义类:class MyDataSource: NSObject Outlet(在故事板和视图控制器中的代码之间链接):@IBOutlet weak var tableView: UITableView ... 在同一个 VC 中,实例化一个 MyDataSource 类型的变量 myDataSource并将 tableView.dataSource 分配给 myDataSource:tableView.dataSource = myDataSource【参考方案3】:这是一个代码示例,显示了 UITableView 的不同数据源和委托。
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
【讨论】:
请注意,对于任何试图在 obj-c 中重新创建它的人来说,在头文件中包含@property (nonatomic, strong) id<MyTVDelegate> delegate;
之类的内容是关键(请注意,该属性必须是强大的)【参考方案4】:
斯威夫特 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!
【讨论】:
以上是关于在单独的文件中设置 UITableView 数据源和委托 - swift的主要内容,如果未能解决你的问题,请参考以下文章
如何在 .xib 文件上创建的 UIViewController 中设置 UITableView
如何在 UITableView 中设置动态单元格分隔线? [复制]
在自定义 UIview 中设置 UItableview 的委托和数据源
如何在 UITableView 中设置 UILabel 的动作