@sportredwhite

Почему view's перерисовывается в cell?

Подскажите плз, почему мои три вьюхи перерисовываются(когда скроллю или поворачиваю экран), которые находятся в кастомном stackView, а данные не изменяются?
(изображения в низу)

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
        }
    }

}


StepTableViewCell:
@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)
    }


CusttomStackView:

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
    }


CustomProgressBar:

class CustomProgressBar: UIView {
    
    var proportion = 1.0
    
    override var intrinsicContentSize: CGSize {
        return CGSize(width: proportion, height: 1.0)
    }

}


5c3c65e642a18338084766.png5c3c6920659e2334904264.png
  • Вопрос задан
  • 113 просмотров
Пригласить эксперта
Ответы на вопрос 2
doublench21
@doublench21 Куратор тега Swift
class CustomProgressBar: UIView {
    
    var proportion = 1.0 { 
      didSet { invalidateIntrinsicContentSize() }
    }

    
    override var intrinsicContentSize: CGSize {
        return CGSize(width: proportion, height: 1.0)
    }

}
Ответ написан
briahas
@briahas
ObjC, Swift, Python
Покажите что у вас в cell.configure(step)

(upd)
"Помучил" ваш код немного. Мдааа... очччень интересная ситуация вырисовалась. Часа два проваландался.
Оказывается, что даже если удалять прогрессбары из стэквьюхи, а затем добавлять - все равно не меняется их размер.

Но, именно такое решение я и нашел - удалять из стэквьюхи все. Просто, я добавлял в не правильном месте.

Короче. Ваш код хорош, просто добавьте
arrangedSubviews.forEach { $0.removeFromSuperview() }
первой строчкой в вашем методе setValues

(upd2)
Подумал тут утром, и понял, что лучше чтоб логика была в одном методе, а не разбросанная по нескольким, поэтому, я бы сделал так:
- убрал из CustomStackView override func layoutSubviews()
- переписал setValues следующим образом:
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)
    }


...у меня работает.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы