我对swift和IOS的编程非常陌生,但我正试图创建一个应用程序。我想创建一个UITableView,其中我有一些标题,如果你点击它们,它们将根据是否打开或关闭。是否可以用标题来实现这个功能,或者我需要使用一个普通的单元格?到目前为止,我就是这样设置的。谢谢你的任何帮助?
编辑。
我现在可以打开和关闭部分,但有些会被删除。 我已经更新了代码,我已经做了这么多的编辑。
她是如何看起来,当我点击的东西。
var settings: [settingOptions] = [
settingOptions(isOpened: true, setting: "appearance", options: ["light mode", "dark mode"]),
settingOptions(isOpened: true, setting: "unit system", options: ["liters & milli liters", "ounzes"]),
settingOptions(isOpened: true, setting: "change goal", options: ["goal"]),
settingOptions(isOpened: true, setting: "how to use", options: []),
settingOptions(isOpened: true, setting: "remove data", options: [])]
@objc func expandOrCollapsSection(_ sender: UIGestureRecognizer){
print("Do something with section")
guard let section = sender.view?.tag else { return }
var indexPaths = [IndexPath]()
for row in settings[section].options.indices {
let indexPath = IndexPath(row: row, section: section)
indexPaths.append(indexPath)
}
let ioOpend = settings[section].isOpened
settings[section].isOpened = !ioOpend
if ioOpend {
tableView.deleteRows(at: indexPaths, with: .none)
} else {
tableView.insertRows(at: indexPaths, with: .none)
}
}
extension AboutVC: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "header") as! SettingOptionCell
cell.setting = settings[indexPath.section].options[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return settings[section].isOpened ? settings[section].options.count : 0
}
func numberOfSections(in tableView: UITableView) -> Int {
return settings.count
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableCell(withIdentifier: "settingCell") as! SettingsCell
cell.setting = settings[section]
cell.selectionStyle = .none
cell.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(expandOrCollapsSection)))
cell.tag = section
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
}
}
class SettingOptionCell: UITableViewCell {
var setting: String? {
didSet {
guard let string = setting else {return}
option.text = string.capitalized
}
}
let option: UILabel = {
let lable = UILabel()
lable.text = "test"
lable.textColor = UIColor.white
lable.font = UIFont(name: "AmericanTypewriter", size: 17)
lable.translatesAutoresizingMaskIntoConstraints = false
return lable
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.addSubview(option)
option.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20).isActive = true
option.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
self.backgroundColor = .none
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class SettingsCell: UITableViewCell {
var setting: settingOptions? {
didSet {
guard let setting = setting else {return}
self.title.text = setting.setting.uppercased()
}
}
var title: UILabel = {
let lable = UILabel()
lable.text = "Test"
lable.font = UIFont(name: "AmericanTypewriter", size: 20)
lable.textColor = .white
lable.translatesAutoresizingMaskIntoConstraints = false
return lable
}()
var container: UIView = {
let view = UIView()
view.clipsToBounds = true
view.backgroundColor = .none
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.backgroundColor = .none
self.isUserInteractionEnabled = true
contentView.addSubview(container)
container.addSubview(title)
title.leftAnchor.constraint(equalTo: container.leftAnchor).isActive = true
title.centerYAnchor.constraint(equalTo: container.topAnchor,constant: 30).isActive = true
container.topAnchor.constraint(equalTo:contentView.topAnchor).isActive = true
container.leftAnchor.constraint(equalTo:contentView.leftAnchor).isActive = true
container.rightAnchor.constraint(equalTo:contentView.rightAnchor).isActive = true
container.bottomAnchor.constraint(equalTo:contentView.bottomAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
是的,它可能与标题,添加 tag
和 UITapGestureRecogniser
所有头视图
添加 isExpanded
设置数据结构的布尔键
给你,写一个手势的动作方法。
@objc func handleTapGesture(_ sender:UIGestureRecogniser) {
let gesture = UIGestureRecognizer.init()
guard let section = gesture.view?.tag else { return }
let indexPaths = [IndexPath]()
for row in settings[section].options.indices {
let indexpath = IndexPath.init(row: row, section: section)
}
// revising the value....
let isExpanded = settings[section].isExpanded
settings[section].isExpanded = !isExpanded
if isExpanded {
tableView.deleteRows(at: indexPaths, with: .fade)
} else {
tableView.insertRows(at: indexPaths, with: .fade)
}
}
小幅修改行数法。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return settings[section].isExpanded ? settings[section].options.count : 0
}
定义变量,用于存储你的表视图部分状态。
var isCollapsed:Bool = true
然后你可以添加 UITapGestureRecognizer 到您的表视图头视图
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableCell(withIdentifier: "settingCell") as! SettingsCell
cell.setting = settings[section]
cell.selectionStyle = .none
cell.isUserInteractionEnabled = true
cell.tag = section
cell.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didMenuItemClicked(_:))))
return cell
}
下一步,你要配置你的表视图单元格,使其按照以下方式运行。isCollapsed 状况
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if !isCollapsed {
let cell = tableView.dequeueReusableCell(withIdentifier: "header") as! SettingOptionCell
cell.setting = settings[indexPath.section].options[indexPath.row]
return cell
}else{
let cell = UITableViewCell()
cell.translatesAutoresizingMaskIntoConstraints = false
cell.heightAnchor.constraint(equalToConstant: 0).isActive = true
cell.widthAnchor.constraint(equalToConstant: 0).isActive = true
return cell
}
}
现在,你可以编写显示、隐藏子项目的功能。
@objc func didMenuItemClicked(_ sender : UITapGestureRecognizer){
isCollapsed = !isCollapsed
myTable.reloadSections([sender.view!.tag], with: .fade)
}
为了解决标题消失的问题,我把用作标题的单元格类型改为UITableViewHeaderFooterView来解决。
class SettingsCell: UITableViewHeaderFooterView {
//init()
}
像这样注册。
tableView.register(SettingsCell.self, forHeaderFooterViewReuseIdentifier: "header")
Dequeue像这样。
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header") as! SettingsCell
cell.setting = settings[section]
cell.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(expandOrCollapsSection)))
cell.tag = section
return cell
}
为了解决打开和关闭部分的问题,我采用了sreekanth的解决方案。