如何从 ViewController 中的 xib (nib) 实例化 UIView / UITableView
Posted
技术标签:
【中文标题】如何从 ViewController 中的 xib (nib) 实例化 UIView / UITableView【英文标题】:How do I instantiate a UIView / UITableView from a xib (nib) in a ViewController 【发布时间】:2015-05-06 18:08:38 【问题描述】:我想显示一个具有分段控件的用户界面,以及分段控件的每个部分的不同表格视图;因此,可以在 2 个表视图(好友和束)之间切换。 为了实现这一点,我做了以下工作
-
在 Storyboard 中创建一个 ViewController
从 ViewController 中删除视图
使用关联的 xib 文件创建一个新的 UIViewController swift 类
将分段控件放在xib的主UIView中
在主 UIView 中放置一个内部 UIView 元素,以占据替换它的表格视图的空间
创建了UITableView的两个子类和对应的xib文件
我想到的一些选项:
我可以将 Interface Builder 中的内部 UIView 的类设置为其中一个表视图的类,但我不知道如何实例化另一个来代替初始视图。如果我创建了重叠的内部 UIView,每个 UIView 都与一个表格视图相关联,并在我切换分段控件时隐藏其中一个,这实际上是可行的,但视图的重叠特性使布局变得困难且不直观。 我想知道怎么做:实例化表格视图来代替单个主 UIView 元素 替代方案:拥有一个 UITableView 子类,该子类具有基于分段控件状态的条件,用于显示哪些数据。我不太喜欢这个,因为它会将表格视图的代码混合在一起。在这种情况下,我什至不再需要使用 xibs,我可以在情节提要中使用一个表格视图来执行此操作。** 视图控制器代码 **
@objc(BuddiesBunchesViewController) class BuddiesBunchesViewController: UIViewController
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBOutlet weak var tableView: UIView!
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
// Instantiate tableView here to BuddiesTableView
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
@IBAction func segmentedControlIndexChanged(sender: AnyObject)
switch segmentedControl.selectedSegmentIndex
case 0: // Buddies
// Set tableview to the buddies table view
case 1: // Bunches
// Set tableview to the buddies table view
default:
break;
** 表格视图 **
@IBDesignable class BuddiesTableView: UITableView, UITableViewDataSource, UITableViewDelegate
var view: UIView!
var nibName: String = "BuddiesTableView"
//init
override init(frame: CGRect)
// set properties
super.init(frame: frame)
// Set anything that uses the view or visible bounds
setup()
required init(coder aDecoder: NSCoder)
//set properties
super.init(coder: aDecoder)
// Setup
setup()
func setup()
view = loadViewFromNib()
view.frame = self.bounds
view.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
addSubview(view)
func loadViewFromNib() -> UIView
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: nibName, bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
return view
// MARK: - Table View
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 10
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell")
cell.textLabel?.text = "\(indexPath.row)"
return cell
【问题讨论】:
【参考方案1】:我个人不会创建两个表视图并将它们交换出来。两者之间唯一的显着区别是它们是不同的实例,您可以在数据源代码中进行测试。他们会指向不同的数据源吗?为什么不即时更改数据源,而不是表视图?
创建一个表格视图。创建两个(或更多)类作为数据源(可能还有委托)。如果它们有任何共同的行为,它们可以基于一个共同的超类。
当分段控件值发生变化时,只需将表格视图的 dataSource 属性更改为指向具有该状态代码的类。如果更改数据源不会自动重新加载它,您可能还需要调用 -reloadData。
@IBOutlet private weak var tableView: UITableView!
let moviesDataSource = MyMoviesDataSource()
let tvShowsDataSource = MyTVShowsDataSource()
@IBAction func segmentedControlTouched(sender: UISegmentedControl)
switch sender.selectedSegmentIndex
case 0:
self.tableView.dataSource = self.moviesDataSource
self.tableView.delegate = self.moviesDataSource
case 1:
self.tableView.dataSource = self.tvShowsDataSource
self.tableView.delegate = self.tvShowsDataSource
self.tableView.reloadData()
【讨论】:
糟糕。 @Amit89 打败了我。 好的,我从没想过移出 tableview 数据源并委托给单独的类。那么在段控制更改时,我将如何交换这些类?你能提供一点代码吗?【参考方案2】:我的解决方案如下。
您有一个具有两个段的段控件,因此您可以只拥有一个UITableView
对象并根据段控件selectedSegmentIndex
编号更改数据源,然后重新加载表视图,而不是拥有两个表视图。在情节提要中,将表格视图放在UIVIewController
的顶部并为此创建一个@IBOutlet
。
【讨论】:
如果两个表格视图需要不同类型的自定义单元格怎么办?其中一个表格视图需要标题,而另一个不需要,所以我认为这个解决方案不能解决这些情况,不是吗? 在 UIViewController 之上的表格视图中,创建两个不同的原型单元格,并为每个单元格创建两个 UITableViewCell 子类,并根据段控件使用所需的单元格。对于标题,对于标题和自定义标题视图,我们有委托方法,在那里检查您需要标题详细信息的哪个段,对于另一个返回空字符串“”作为标题,为标题视图返回 nil。以上是关于如何从 ViewController 中的 xib (nib) 实例化 UIView / UITableView的主要内容,如果未能解决你的问题,请参考以下文章
从 XIB Viewcontroller 中的 segmentcontrol 到 Storyboard Viewcontroller
如何通过推送从 xib 转换到 ViewController
从 xib 文件中的操作按钮推送另一个 Viewcontroller
如何从 UIView 类的 xib 文件导航到 ViewController
iOS - 使用 xib 中的 tabBarController 将数据从一个 viewController 传递到另一个 viewController