Answer the question
In order to leave comments, you need to log in
Why is view's redrawn to cell?
Plz tell me why my three views are redrawn (when I scroll or rotate the screen), which are in a custom stackView, but the data does not change?
(images at bottom)
ViewController:
let cells: [String] = ["StepCell", "GoalCell"]
var steps: [Step] = [] {
didSet {
tableView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
spinner.startAnimating()
Network.shared.loadDataUser { (response) in
switch response {
case .success(let steps):
DispatchQueue.main.async {
self.steps = steps
self.spinner.stopAnimating()
}
case .refuse(let error):
print(error)
}
}
}
extension StepViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return steps.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cells.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = cells[indexPath.row]
let step = steps[indexPath.section]
switch cellIdentifier {
case "StepCell":
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! StepTableViewCell
cell.configure(step)
return cell
case "GoalCell":
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! GoalTableViewCell
return cell
default:
let cell = UITableViewCell()
return cell
}
}
}
@IBOutlet weak var customStackView: CustomStackView!
var width: Int = 0
func configure(_ step: Step) {
dateLabel.text = getStringDate(for: step)
myStepLabel.text = "\(step.getAllStep())"
walkLabel.text = step.walk.description
aerobicLabel.text = step.aerobic.description
runLabel.text = step.run.description
let allStep = step.getAllStep()
let walk = getProportion(for: step.walk, allStep: allStep)
let aerobic = getProportion(for: step.aerobic, allStep: allStep)
let run = getProportion(for: step.run, allStep: allStep)
customStackView.setValues(walk, aerobic, run)
}
private func getStringDate(for step: Step) -> String {
let formatter = DateFormatter.ddMMyyyy
return formatter.string(from: step.date)
}
private func getProportion(for value: Int, allStep: Int) -> Double {
return 100.0 * Double(value) / Double(allStep)
}
required init(coder: NSCoder) {
super.init(coder: coder)
distribution = .fillProportionally
axis = .horizontal
spacing = 5.0
addArrangedSubview(walk)
addArrangedSubview(aerobic)
addArrangedSubview(run)
}
func setValues(_ walk: Double, _ aerobic: Double, _ run: Double) {
self.walk.proportion = walk
self.aerobic.proportion = aerobic
self.run.proportion = run
}
class CustomProgressBar: UIView {
var proportion = 1.0
override var intrinsicContentSize: CGSize {
return CGSize(width: proportion, height: 1.0)
}
}
Answer the question
In order to leave comments, you need to log in
class CustomProgressBar: UIView {
var proportion = 1.0 {
didSet { invalidateIntrinsicContentSize() }
}
override var intrinsicContentSize: CGSize {
return CGSize(width: proportion, height: 1.0)
}
}
Show what you have in cell.configure(step)
"Tormented" your code a bit. Mdaaa ... a very interesting situation has emerged. Failed for two hours.
It turns out that even if you remove progressbars from the stackview and then add them, their size still does not change.
But, this is exactly the solution I found - to remove everything from the stackview. It's just that I added in the wrong place.
Briefly speaking. Your code is good, just add
arrangedSubviews.forEach { $0.removeFromSuperview() }
the first line in your method setValues
override func layoutSubviews()
setValues
as follows:func setValues(_ walkValue: Double, _ aerobicValue: Double, _ runValue: Double) {
arrangedSubviews.forEach { $0.removeFromSuperview() }
setNeedsLayout()
layoutIfNeeded()
walk.proportion = walkValue
aerobic.proportion = aerobicValue
run.proportion = runValue
addArrangedSubview(walk)
addArrangedSubview(aerobic)
addArrangedSubview(run)
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question