所以我是新手,正在尝试一些可重用性。我有一个名为SingleButtonFooterView
的类,它继承了UIView
的一个类,并且UI在.xib
中完成。
现在我想在UITableViewCell
中使用它。我已经尝试了几乎所有可能的解决方案,但对我没有用。
课程代码:
class SingleButtonFooterView: UIView {
@IBOutlet weak var button: Button50!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit(){
let view = UINib(nibName: "SingleButtonFooterView", bundle: nil).instantiate(withOwner: self, options: nil).first as! UIView
view.frame = self.bounds
self.addSubview(view)
}
override func awakeFromNib() {
super.awakeFromNib()
button.backgroundColor = .clear
button.layer.cornerRadius = 5
button.layer.masksToBounds = true
button.titleLabel?.font = UIFont.futura(with: .medium, size: 16)
button.setTitleColor(.white, for: .normal)
self.contentMode = .scaleAspectFit
self.layer.masksToBounds = true
}
}
现在cellForRowAt:
let cellId = "SingleButtonFooterView"
var cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
if cell == nil {
cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: cellId)
let subView = SingleButtonFooterView(frame: cell.frame)
cell.contentView.attachViewWithConstraints(subView)
let _ = subView.viewLoadedFromNibAttached(name: cellId)
}
return cell
和我的VC类的viewDidLoad()
中。
tableView.register(UINib(nibName: "SingleButtonFooterView", bundle: nil), forCellReuseIdentifier: "SingleButtonFooterView")
简而言之 -> 我想在UITableViewCell中使用UIView类(使用界面生成器-> .xib完成的UI)
答案 0 :(得分:1)
如果我可以建议您做点什么,那就“按书”做。
创建一个自定义单元格,然后.xib
。然后,您可以使用UIView
s做任何您想做的事情(请记住,您可以创建自己的类并将其放在xib中,方法是在此处更改类:
在一个类中有awakeFromNib
和Init
的情况下,某种程度上讲代码是闻起来的,因为您可以使用.xib
或code
来创建视图。
请记住,从VC添加子视图总是有风险的,因为您需要进行回收,这意味着除非您处理这种情况,否则该子视图可能会保留并且不被使用。
记住prepareForReuse()
来处理细胞的回收。
答案 1 :(得分:0)
您在这里有两个问题:
1)
Bundle.main.loadNibNamed(name, owner: self, options: nil)
中的viewLoadedFromNibAttached
(如果您使用与另一个问题完全相同的代码)
并且commonInit
中的笔尖负载相同。
您必须决定将其放置在哪里,IMO可以摆脱
let subView = SingleButtonFooterView(frame: cell.frame)
cell.contentView.attachViewWithConstraints(subView)
let _ = subView.viewLoadedFromNibAttached(name: cellId)
并将该部分放到单元格中(通过这种方式,您可以轻松维护SingleButtonFooterView
的生命周期
2)猜测:xib的文件所有者为空或使用错误的类,这就是commonInit
和required init?(coder aDecoder: NSCoder)
导致infinite loop的原因
编辑:
步骤1:子类UITableViewCell
,我们将其称为SingleButtonCell
第2步:自定义视图(在您的情况下为SingleButtonFooterView
)。注意!文件的所有者应为类本身-> SingleButtonFooterView
@IBOutlet var contentView: UIView!
override init(frame: CGRect) {
super.init(frame: frame)
loadXib()
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
loadXib()
}
private func loadXib() {
Bundle.main.loadNibNamed(String(describing: type(of: self)), owner: self, options: nil)
addSubview(contentView)
contentView.frame = bounds
}
这就是我用来从.xib加载视图的方法。 contentView
是.xib文件中主视图的出口
第3步:此处有两个选择:
选项3.1:(易于维护IMO)
使用SingleButtonCell
创建它自己的.xib文件
3.1.1:在单元格的xib(SingleButtonCell.xib
)中添加视图,并将其类更改为SingleButtonFooterView
选项3.2:不要创建单元xib。而是实例化单元格中的视图(SingleButtonFooterView
)并将其添加为子视图(如果需要,添加约束)。在这里,您必须小心在哪里实例化视图,因为有机会多次添加视图
答案 2 :(得分:0)
我看到的是dequeueReusableCell(withIdentifier:for:)
从不返回nil。因此,您的nil-check中的代码将永远不会被调用。您可能会想到“旧” dequeueReusableCell(withIdentifier:)
,它可以返回nil并且可以像您一样使用。
由于它永远不会为零,因此您需要一个附加参数,说“ hasBeenInitialized”以跟踪是否已添加自定义UIView。
// In loading viewDidLoad, register cellId for type for tableView
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
if !hasBeenInitialized {
// Load view from xib
// Add view as subview to cell contentview
// Add surrounding constraints
hasBeenInitialized = true
}
return cell