我有一个UI结构,其中有一个水平scrollView嵌套5个tableViews –每个代表一周中的一天。我添加了一个UISwitch来将周末添加到一周中,因此当用户打开它时,将另外两个tableview-subviews添加到scrollView中。到目前为止一切顺利,但是切换更改仅在我重新启动该应用程序时才生效。看起来像ViewDidLoad()可以实现,但是没有其他事情。我添加了一个名为isWeekOn的布尔变量。它的状态通过viewDidLoad管理:
isWeekendOn = UserDefaults.standard.bool(forKey: "switchState")
dayTableViews = fiveOrSevenDayTableViews()
其中FiveOrSevenTableViews()是一个闭包,它返回具有正确计数的tableview数组,而dayTableViews是我的本地数组变量。
lazy var fiveOrSevenDayTableViews: () -> [DayTableView] = {
if self.isWeekendOn == false {
return [self.mondayTableView, self.tuesdayTableview, self.wednesdayTableview, self.thursdayTableView, self.fridayTableView]
} else {
return [self.mondayTableView, self.tuesdayTableview, self.wednesdayTableview, self.thursdayTableView, self.fridayTableView, self.saturdayTableView,self.sundayTableView]
}
}
[我在isWeekendOn上添加了didSet属性观察器,该观察器还调用setupViews(),其中表视图的数量也通过调用FiveOrSevenTableViews闭包来确定。
var isWeekendOn: Bool = false {
didSet {
print("LessonVC IsWeekendon: ",isWeekendOn)
dayTableViews = fiveOrSevenDayTableViews()
setupViews()
print("didset daytableviews", fiveOrSevenDayTableViews().count)
}
}
我的setupViews()如下所示:
func setupViews() {
setupScrollView()
let numberOfTableViews = CGFloat(dayTableViews.count)
let stackView = UIStackView(arrangedSubviews: fiveOrSevenDayTableViews())
print("setupViews stacview subviews count", stackView.arrangedSubviews.count)
stackView.axis = .horizontal
stackView.distribution = .fillEqually
scrollView.addSubview(stackView)
setupStackViewConstraints(stackView, numberOfTableViews)
}
和setupScrollView():
private func setupScrollView() {
let numberOfTableViews = CGFloat(dayTableViews.count)
print("setupScrollview dableviews", numberOfTableViews)
scrollView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height:0)
scrollView.contentSize = CGSize(width: view.frame.width * numberOfTableViews, height: 0)
view.addSubview(scrollView)
setupScrollviewConstraints()
}
所有的打印语句都被正确调用,所以我想知道为什么更改实际上不能实时生效,而只能重新启动。
我尝试过的事情:
按照@maniponken的建议,我做了一个看起来像这样的函数:
func readdStackView(_ stackView: UIStackView) { stackView.removeFromSuperview()
setupViews() }
比我在isWeekendOn didSet观察器中称呼它。不幸的是没有解决。
尝试一下,它不是堆栈视图,但是可以用于向ViewController添加(和删除)表视图。此方法未使用情节提要[]
在您的viewcontroller中,包含tableview
import Foundation import UIKit class SevenTableviews: UIViewController, UITableViewDelegate, UITableViewDataSource { let tableView1: UITableView = { let tv = UITableView() tv.backgroundColor = .white tv.separatorStyle = .none return tv }() let tableView2: UITableView = { let tv = UITableView() tv.backgroundColor = .white tv.separatorStyle = .none return tv }() let tableSwitch: UISwitch = { let switchBtn = UISwitch() switchBtn.addTarget(self, action: #selector(switchTables), for: .touchUpInside) return switchBtn }() var isTableTwoShowing = false let reuseIdentifier = "DaysCell" var days = ["monday", "tuesday", "wednesday", "thursday", "friday"] var weekendDays = ["saturday", "sunday"] override func viewDidLoad() { super.viewDidLoad() setupTableview() } func setupTableview() { tableView1.dataSource = self tableView1.delegate = self tableView1.register(DaysTableviewCell.self, forCellReuseIdentifier: reuseIdentifier) view.addSubview(tableView1) tableView1.anchor(top: view.safeAreaLayoutGuide.topAnchor, left: view.leftAnchor, bottom: view.centerYAnchor, right: view.rightAnchor) if isTableTwoShowing == true { tableView2.dataSource = self tableView2.delegate = self tableView2.register(DaysTableviewCell.self, forCellReuseIdentifier: reuseIdentifier) view.addSubview(tableView2) tableView2.anchor(top: view.centerYAnchor, left: view.leftAnchor, bottom: view.safeAreaLayoutGuide.bottomAnchor, right: view.rightAnchor) } view.addSubview(tableSwitch) tableSwitch.anchor(bottom: view.safeAreaLayoutGuide.bottomAnchor, right: view.rightAnchor, paddingBottom: 24, paddingRight: 12) } @objc func switchTables() { if tableSwitch.isOn { isTableTwoShowing = true setupTableview() } else { isTableTwoShowing = false tableView2.removeFromSuperview() } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if tableView == tableView1 { return days.count } else if tableView == tableView2 { return weekendDays.count } else { return 0 } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier) as! DaysTableviewCell if tableView == tableView1 { cell.dateLabel.text = days[indexPath.row] return cell } else { cell.dateLabel.text = weekendDays[indexPath.row] return cell } } }
在您的tableviewCell-class中:
import Foundation import UIKit class DaysTableviewCell: UITableViewCell { let identifier = "DaysCell" let cellContainer: UIView = { let view = UIView() view.backgroundColor = .white view.backgroundColor = Colors.boxBack view.setCellShadow() return view }() let dateLabel: UILabel = { let label = UILabel() label.font = UIFont.systemFont(ofSize: 20) return label }() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setupViews() } func setupViews() { selectionStyle = .none addSubview(cellContainer) cellContainer.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 4, paddingLeft: 8, paddingBottom: 4, paddingRight: 8, height: 35) cellContainer.addSubview(dateLabel) dateLabel.anchor(top: cellContainer.topAnchor, left: cellContainer.leftAnchor, bottom: cellContainer.bottomAnchor, right: cellContainer.rightAnchor, paddingTop: 4, paddingLeft: 8, paddingBottom: 4, paddingRight: 8) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
我在两个表视图中都使用相同的单元格类,但是您可以自行决定如何执行此操作。
此外,我的约束设置有我在教程中找到的扩展名:
extension UIView { func anchor(top: NSLayoutYAxisAnchor? = nil, left: NSLayoutXAxisAnchor? = nil, bottom: NSLayoutYAxisAnchor? = nil, right: NSLayoutXAxisAnchor? = nil, paddingTop: CGFloat? = 0, paddingLeft: CGFloat? = 0, paddingBottom: CGFloat? = 0, paddingRight: CGFloat? = 0, width: CGFloat? = nil, height: CGFloat? = nil) { translatesAutoresizingMaskIntoConstraints = false if let top = top { topAnchor.constraint(equalTo: top, constant: paddingTop!).isActive = true } if let left = left { leftAnchor.constraint(equalTo: left, constant: paddingLeft!).isActive = true } if let bottom = bottom { if let paddingBottom = paddingBottom { bottomAnchor.constraint(equalTo: bottom, constant: -paddingBottom).isActive = true } } if let right = right { if let paddingRight = paddingRight { rightAnchor.constraint(equalTo: right, constant: -paddingRight).isActive = true } } if let width = width { widthAnchor.constraint(equalToConstant: width).isActive = true } if let height = height { heightAnchor.constraint(equalToConstant: height).isActive = true } } }
希望这会有所帮助
夫妇注释: