如何在自定义视图中嵌入 UITableView
How to embed a UITableView in a custom view
目标
我想创建一个将 UITableView 作为子视图的自定义视图。
自定义视图以编程方式创建 table 视图。但是,对于外界(即 ViewController),自定义视图本身似乎是 table 视图。
我试过的
import UIKit
class CustomTableView: UIView {
// Do I make outlets?
//@IBOutlet var dataSource: UITableViewDataSource?
//@IBOutlet var delegate: UITableViewDelegate?
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect){
super.init(frame: frame)
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func layoutSubviews() {
super.layoutSubviews()
var tableView: UITableView!
tableView = UITableView(frame: self.bounds)
// I'm not sure how to set the delegate and dataSource
// tableView.dataSource = ???
// tableView.delegate = ???
self.addSubview(tableView)
}
}
以编程方式创建 UITableView 并将其作为子视图添加到自定义视图父级后,我不知道如何让自定义视图像 table 视图一样工作。也就是说,我不知道如何让自定义视图在视图控制器和 delegate
和 dataSource
的 table 视图之间进行通信。
我读过的内容
这些文章看起来不错,但我有点迷茫。
如何使自定义视图在委托和数据源方面表现得像它自己的 table 子视图?
不是最优雅的,但是跳出一个层次:
class MyCustomViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
override func viewDidLoad() {
myCustomView = CustomTableView()
myCustomView.frame = ... /* layout programatically */
/* Alternatively to the above 2 lines,
lay out myCustomView in StoryBoard,
and capture it as an @IBOutlet. It will then be ready here
to muck with, well before it gets displayed and needs the data */
myCustomView.tableView.delegate = self
myCustomView.tableView.dataSource = self
}
/* Now implement all your dataSource and delegate methods */
}
* 重要 *
您缺少的关键是 tableView
必须是自定义视图的存储 属性。这很重要,需要从一个愚蠢的本地人那里得到提升!它也应该在 awakeFromNib() 函数中初始化,即使您不知道帧大小。然后在布局时重置其框架。
在更高层次上,我不知道 "What You're Really Trying To Do." 在自定义视图中嵌入 UITableView 实际上可能不是正确的实现技术;考虑只在主视图中布置 UITableView。然后,如果您需要围绕它进行装饰,请将它们作为单独的视图放在 StoryBoard 中。
解决方案是使 tableView
成为自定义 class 的 属性(如 @BaseZen 所建议的)。然后在自定义 class 中提供属性和方法,以模仿和传递 tableView
.
所需的属性和方法
import UIKit
@IBDesignable class UICustomTableView: UIView {
private var myTableView: UITableView
required init(coder aDecoder: NSCoder) {
myTableView = UITableView()
super.init(coder: aDecoder)
}
override init(frame: CGRect){
myTableView = UITableView()
super.init(frame: frame)
}
override func awakeFromNib() {
super.awakeFromNib()
}
// TODO: @IBOutlet still can't be set in IB
@IBOutlet weak var delegate: UITableViewDelegate? {
get {
return myTableView.delegate
}
set {
myTableView.delegate = newValue
}
}
// TODO: @IBOutlet still can't be set in IB
@IBOutlet weak var dataSource: UITableViewDataSource? {
get {
return myTableView.dataSource
}
set {
myTableView.dataSource = newValue
}
}
func registerClass(cellClass: AnyClass?, forCellReuseIdentifier identifier: String) {
myTableView.registerClass(cellClass, forCellReuseIdentifier: identifier)
}
func dequeueReusableCellWithIdentifier(identifier: String) -> UITableViewCell? {
return myTableView.dequeueReusableCellWithIdentifier(identifier)
}
override func layoutSubviews() {
super.layoutSubviews()
// ...
// setup UITableView
myTableView.frame = self.bounds
self.addSubview(myTableView)
// ...
}
}
然后就可以正常使用了UITableView
:
import UIKit
class TableViewDemoVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var customTableView: UICustomTableView!
var items: [String] = ["One", "Two", "Three"]
override func viewDidLoad() {
super.viewDidLoad()
// setup the table view from the IB reference
customTableView.delegate = self
customTableView.dataSource = self
customTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell = self.customTableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell!
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
// ...
}
目标
我想创建一个将 UITableView 作为子视图的自定义视图。
自定义视图以编程方式创建 table 视图。但是,对于外界(即 ViewController),自定义视图本身似乎是 table 视图。
我试过的
import UIKit
class CustomTableView: UIView {
// Do I make outlets?
//@IBOutlet var dataSource: UITableViewDataSource?
//@IBOutlet var delegate: UITableViewDelegate?
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect){
super.init(frame: frame)
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func layoutSubviews() {
super.layoutSubviews()
var tableView: UITableView!
tableView = UITableView(frame: self.bounds)
// I'm not sure how to set the delegate and dataSource
// tableView.dataSource = ???
// tableView.delegate = ???
self.addSubview(tableView)
}
}
以编程方式创建 UITableView 并将其作为子视图添加到自定义视图父级后,我不知道如何让自定义视图像 table 视图一样工作。也就是说,我不知道如何让自定义视图在视图控制器和 delegate
和 dataSource
的 table 视图之间进行通信。
我读过的内容
这些文章看起来不错,但我有点迷茫。
如何使自定义视图在委托和数据源方面表现得像它自己的 table 子视图?
不是最优雅的,但是跳出一个层次:
class MyCustomViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
override func viewDidLoad() {
myCustomView = CustomTableView()
myCustomView.frame = ... /* layout programatically */
/* Alternatively to the above 2 lines,
lay out myCustomView in StoryBoard,
and capture it as an @IBOutlet. It will then be ready here
to muck with, well before it gets displayed and needs the data */
myCustomView.tableView.delegate = self
myCustomView.tableView.dataSource = self
}
/* Now implement all your dataSource and delegate methods */
}
* 重要 *
您缺少的关键是 tableView
必须是自定义视图的存储 属性。这很重要,需要从一个愚蠢的本地人那里得到提升!它也应该在 awakeFromNib() 函数中初始化,即使您不知道帧大小。然后在布局时重置其框架。
在更高层次上,我不知道 "What You're Really Trying To Do." 在自定义视图中嵌入 UITableView 实际上可能不是正确的实现技术;考虑只在主视图中布置 UITableView。然后,如果您需要围绕它进行装饰,请将它们作为单独的视图放在 StoryBoard 中。
解决方案是使 tableView
成为自定义 class 的 属性(如 @BaseZen 所建议的)。然后在自定义 class 中提供属性和方法,以模仿和传递 tableView
.
import UIKit
@IBDesignable class UICustomTableView: UIView {
private var myTableView: UITableView
required init(coder aDecoder: NSCoder) {
myTableView = UITableView()
super.init(coder: aDecoder)
}
override init(frame: CGRect){
myTableView = UITableView()
super.init(frame: frame)
}
override func awakeFromNib() {
super.awakeFromNib()
}
// TODO: @IBOutlet still can't be set in IB
@IBOutlet weak var delegate: UITableViewDelegate? {
get {
return myTableView.delegate
}
set {
myTableView.delegate = newValue
}
}
// TODO: @IBOutlet still can't be set in IB
@IBOutlet weak var dataSource: UITableViewDataSource? {
get {
return myTableView.dataSource
}
set {
myTableView.dataSource = newValue
}
}
func registerClass(cellClass: AnyClass?, forCellReuseIdentifier identifier: String) {
myTableView.registerClass(cellClass, forCellReuseIdentifier: identifier)
}
func dequeueReusableCellWithIdentifier(identifier: String) -> UITableViewCell? {
return myTableView.dequeueReusableCellWithIdentifier(identifier)
}
override func layoutSubviews() {
super.layoutSubviews()
// ...
// setup UITableView
myTableView.frame = self.bounds
self.addSubview(myTableView)
// ...
}
}
然后就可以正常使用了UITableView
:
import UIKit
class TableViewDemoVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var customTableView: UICustomTableView!
var items: [String] = ["One", "Two", "Three"]
override func viewDidLoad() {
super.viewDidLoad()
// setup the table view from the IB reference
customTableView.delegate = self
customTableView.dataSource = self
customTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell = self.customTableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell!
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
// ...
}