iam*_*rak 33 uitableview xib ios swift
我可以在编程上创建简单的自定义viewForHeaderInSection,如下所示.但是我想要做更复杂的事情,可能是与不同类的连接,并像tableView单元一样到达它们的属性.简单地说,我想看看我做了什么.
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if(section == 0) {
let view = UIView() // The width will be the same as the cell, and the height should be set in tableView:heightForRowAtIndexPath:
let label = UILabel()
let button = UIButton(type: UIButtonType.System)
label.text="My Details"
button.setTitle("Test Title", forState: .Normal)
// button.addTarget(self, action: Selector("visibleRow:"), forControlEvents:.TouchUpInside)
view.addSubview(label)
view.addSubview(button)
label.translatesAutoresizingMaskIntoConstraints = false
button.translatesAutoresizingMaskIntoConstraints = false
let views = ["label": label, "button": button, "view": view]
let horizontallayoutContraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[label]-60-[button]-10-|", options: .AlignAllCenterY, metrics: nil, views: views)
view.addConstraints(horizontallayoutContraints)
let verticalLayoutContraint = NSLayoutConstraint(item: label, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0)
view.addConstraint(verticalLayoutContraint)
return view
}
return nil
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
Run Code Online (Sandbox Code Playgroud)
有没有人解释如何使用xib创建自定义tableView标题视图?我遇到过旧的Obj-C主题,但我是Swift语言的新手.如果有人解释详细,那就太好了.
1.issue:按钮@IBAction不与我的ViewController连接.(固定)
使用File的Owner,ViewController基类解决(点击左侧轮廓菜单.)
2.issue:标题高度问题(固定)
解决了在viewForHeaderInSection:方法中添加headerView.clipsToBounds = true的问题.
对于约束警告, 这个答案解决了我的问题:
当我在viewController中使用此方法添加ImageView甚至相同的高度约束时,它流过tableView行看起来像图片.
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 120
}
Run Code Online (Sandbox Code Playgroud)
如果我使用,则在viewDidLoad中自动调整ScrollViewInsets,在这种情况下,图像流在navigationBar下.-固定-
self.automaticallyAdjustsScrollViewInsets = false
Run Code Online (Sandbox Code Playgroud)
3.issue:如果按下查看(固定)
@IBAction func didTapButton(sender: AnyObject) {
print("tapped")
if let upView = sender.superview {
if let headerView = upView?.superview as? CustomHeader {
print("in section \(headerView.sectionNumber)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*Rob 84
基于NIB的标头的典型过程是:
创建UITableViewHeaderFooterView至少包含标签出口的子类.您可能还想给它一些标识符,通过该标识符可以对此标题对应的部分进行反向工程.同样,您可能希望指定一个协议,标头可以通过该协议通知视图控制器事件(如点击按钮).因此,在Swift 3及更高版本中:
// if you want your header to be able to inform view controller of key events, create protocol
protocol CustomHeaderDelegate: class {
func customHeader(_ customHeader: CustomHeader, didTapButtonInSection section: Int)
}
// define CustomHeader class with necessary `delegate`, `@IBOutlet` and `@IBAction`:
class CustomHeader: UITableViewHeaderFooterView {
static let reuseIdentifier = "CustomHeader"
weak var delegate: CustomHeaderDelegate?
@IBOutlet weak var customLabel: UILabel!
var sectionNumber: Int! // you don't have to do this, but it can be useful to have reference back to the section number so that when you tap on a button, you know which section you came from; obviously this is problematic if you insert/delete sections after the table is loaded; always reload in that case
@IBAction func didTapButton(_ sender: AnyObject) {
delegate?.customHeader(self, didTapButtonInSection: section)
}
}
Run Code Online (Sandbox Code Playgroud)创建NIB.就个人而言,我给NIB提供了与基类相同的名称,以简化我项目中文件的管理,避免混淆.无论如何,关键步骤包括:
创建视图NIB,或者如果以空NIB开始,则向NIB添加视图;
将视图的基类设置为您的UITableViewHeaderFooterView子类(在我的示例中CustomHeader);
在IB中添加控件和约束;
胡克@IBOutlet在您的银行代码网点引用;
把按钮连接到@IBAction; 和
对于NIB中的根视图,请确保将背景颜色设置为"默认",否则您将收到有关更改背景颜色的恼人警告.
在viewDidLoad视图控制器中,注册NIB.在Swift 3及更高版本中:
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "CustomHeader", bundle: nil), forHeaderFooterViewReuseIdentifier: CustomHeader.reuseIdentifier)
}
Run Code Online (Sandbox Code Playgroud)在viewForHeaderInSection,使用您在上一步中指定的相同标识符使可重用视图出列.完成后,您现在可以使用您的插座,您不必对编程创建的约束等做任何事情.您需要做的唯一事情(对于按钮的协议工作)是指定其委托.例如,在Swift 3中:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "CustomHeader") as! CustomHeader
headerView.customLabel.text = content[section].name // set this however is appropriate for your app's model
headerView.sectionNumber = section
headerView.delegate = self
return headerView
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44 // or whatever
}
Run Code Online (Sandbox Code Playgroud)显然,如果您要将视图控制器指定delegate为标题视图中的按钮,则必须符合该协议:
extension ViewController: CustomHeaderDelegate {
func customHeader(_ customHeader: CustomHeader, didTapButtonInSection section: Int) {
print("did tap button", section)
}
}
Run Code Online (Sandbox Code Playgroud)当我列出所涉及的所有步骤时,这一切听起来都很混乱,但是一旦你做了一次或两次,这真的很简单.我认为它比以编程方式构建标题视图更简单.
在亚特的回答中,他抗议:
简单来说,问题在于,你不能通过在身份检查器中声明它而将
UIView一个笔尖神奇地变成一个笔尖UITableViewHeaderFooterView.
这根本不正确.如果使用上述基于NIB的方法,则为此标头视图的根视图实例化的类是UITableViewHeaderFooterView子类,而不是a UIView.它实例化您为NIB根视图为基类指定的任何类.
但是,正确的是,这个类的某些属性(特别是contentView)在这个基于NIB的方法中没有使用.这真的应该是可选属性,就像textLabel和detailTextLabel是(或更好,还应该加上适当的支持UITableViewHeaderFooterView在IB).我同意这在Apple的设计上是糟糕的设计,但它让我觉得这是一个草率的,特殊的细节,但考虑到表格视图中的所有问题,这是一个小问题.例如,经过这么多年,我们仍然无法在故事板中做原型页眉/页脚视图并且必须完全依赖于这些NIB和类注册技术.
但是,得出一个人不能使用的结论是不正确的,这是一种register(_:forHeaderFooterViewReuseIdentifier:)自iOS 6以来一直在使用的API方法.让我们不要用洗澡水把婴儿扔出去.
请参阅Swift 2再现的此答案的上一版本.
mat*_*att 31
Rob的回答虽然听起来很有说服力并且经受住了时间的考验,但却是错误的.很难单独反对压倒性的人群"接受的智慧"和无数的赞成,但我会试着鼓起勇气说出真相.
简单来说,问题是你不能仅仅通过在身份检查器中声明它,将nib中的UIView神奇地变成UITableViewHeaderFooterView.UITableViewHeaderFooterView具有对其正确操作至关重要的重要功能,并且无论您如何投射 UIView ,都缺少它们.
UITableViewHeaderFooterView有一个contentView,并且必须将所有自定义子视图添加到此,而不是UITableViewHeaderFooterView.
但是一个UIView神秘地投射为UITableViewHeaderFooterView contentView在笔尖中缺少这个.因此,当Rob说"在IB中添加你的控件和约束"时,他会让你直接将子视图添加到UITableViewHeaderFooterView,而不是它contentView.因此,标头最终配置错误.
此问题的另一个迹象是您不允许为UITableViewHeaderFooterView提供背景颜色.如果您这样做,您将在控制台中收到此消息:
不推荐在UITableViewHeaderFooterView上设置背景颜色.请将具有所需背景颜色的自定义UIView设置为backgroundView属性.
但是在笔尖中,您无法帮助在UITableViewHeaderFooterView上设置背景颜色,并且您确实在控制台中获得了该消息.
那么这个问题的正确答案是什么?有没有可能的答案.苹果公司在这里做出了巨大的努力.他们提供了一种方法,允许您将nib注册为UITableViewHeaderFooterView的源,但对象库中没有UITableViewHeaderFooterView.因此这种方法毫无用处.在笔尖中正确设计UITableViewHeaderFooterView 是不可能的.
这是Xcode中的一个巨大错误.我在2013年就此问题提交了一份错误报告,它仍然坐在那里,开放.我年复一年地改变了这个漏洞,苹果不断推回,说"尚未确定如何或何时解决问题." 所以他们承认这个错误,但他们对此无动于衷.
但是,你可以做的是在nib中设计一个普通的UIView,然后在代码中(在你的实现中viewForHeaderInSection),从nib手动加载视图并将其填充到contentView标题视图中.
例如,假设我们想要在笔尖中设计标题,并且我们在标题中有一个标签,我们想要连接一个插座lab.然后我们需要一个自定义头类和一个自定义视图类:
class MyHeaderView : UITableViewHeaderFooterView {
weak var content : MyHeaderViewContent!
}
class MyHeaderViewContent : UIView {
@IBOutlet weak var lab : UILabel!
}
Run Code Online (Sandbox Code Playgroud)
我们注册了标题视图的类,而不是nib:
self.tableView.register(MyHeaderView.self,
forHeaderFooterViewReuseIdentifier: self.headerID)
Run Code Online (Sandbox Code Playgroud)
在视图xib文件中,我们将视图声明为MyHeaderViewContent - 而不是 MyHeaderView.
在viewForHeaderInSection,我们从nib中取出视图,将其填充到contentView标题中,并配置对它的引用:
override func tableView(_ tableView: UITableView,
viewForHeaderInSection section: Int) -> UIView? {
let h = tableView.dequeueReusableHeaderFooterView(
withIdentifier: self.headerID) as! MyHeaderView
if h.content == nil {
let v = UINib(nibName: "MyHeaderView", bundle: nil).instantiate
(withOwner: nil, options: nil)[0] as! MyHeaderViewContent
h.contentView.addSubview(v)
v.translatesAutoresizingMaskIntoConstraints = false
v.topAnchor.constraint(equalTo: h.contentView.topAnchor).isActive = true
v.bottomAnchor.constraint(equalTo: h.contentView.bottomAnchor).isActive = true
v.leadingAnchor.constraint(equalTo: h.contentView.leadingAnchor).isActive = true
v.trailingAnchor.constraint(equalTo: h.contentView.trailingAnchor).isActive = true
h.content = v
// other initializations for all headers go here
}
h.content.lab.text = // whatever
// other initializations for this header go here
return h
}
Run Code Online (Sandbox Code Playgroud)
这是可怕和烦人的,但它是你能做的最好的.
创建一个 UITableViewHeaderFooterView 及其对应的 xib 文件。
class BeerListSectionHeader: UITableViewHeaderFooterView {
@IBOutlet weak var sectionLabel: UILabel!
@IBOutlet weak var abvLabel: UILabel!
}
Run Code Online (Sandbox Code Playgroud)
注册笔尖与注册表格视图单元格的方式类似。笔尖名称和重用标识符应与您的文件名匹配。(xib 没有重用 ID。)
func registerHeader {
let nib = UINib(nibName: "BeerListSectionHeader", bundle: nil)
tableView.register(nib, forHeaderFooterViewReuseIdentifier: "BeerListSectionHeader")
}
Run Code Online (Sandbox Code Playgroud)
出列和使用类似于单元格。标识符是文件名。
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "BeerListSectionHeader") as! BeerListSectionHeader
let sectionTitle = allStyles[section].name
header.sectionLabel.text = sectionTitle
header.dismissButton?.addTarget(self, action: #selector(dismissView), for: .touchUpInside)
return header
}
Run Code Online (Sandbox Code Playgroud)
不要忘记标题高度。
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return BeerListSectionHeader.height
}
Run Code Online (Sandbox Code Playgroud)