위의 사진을 보면 12의 값을 받았지만 progressView가 대략 21정도의 값을 나타낸다. progressView가 21 보다 큰 값과 0의 값은 제대로 나타내지만 21 보다 작은 값은 나타내지 못하는 문제가 발생했다.
우선 문제를 해결하기 전 코드는 이렇다.
override func viewDidLoad() {
super.viewDidLoad()
configureProgressView()
fineDustViewModel.observable
.observe(on: MainScheduler.instance)
.subscribe(onNext:{ [weak self] in
self?.setProgressView($0)
})
.disposed(by: disposeBag)
}
private func configureProgressView(){
fineDustProgressView.progressViewStyle = .bar
fineDustProgressView.trackTintColor = #colorLiteral(red: 0.835541904, green: 0.8356826901, blue: 0.8355233073, alpha: 1)
fineDustProgressView.clipsToBounds = true
fineDustProgressView.layer.cornerRadius = 15
fineDustProgressView.layer.sublayers![1].cornerRadius = 15
fineDustProgressView.subviews[1].clipsToBounds = true
fineDustProgressView.progress = 0.0
}
viewDidLoad에서 configureProgressView()를 호출한다. configureProgressView() 함수는 ProgressView를 꾸며주는? 함수이다. 그리고 obsevable을 통해 미세먼지의 값을 받고 setProgressView() 함수를 호출한다.
setProgressView()함수는 아래와 같다.
private func setProgressView(_ fineDustAPIData: FineDustAPIData){
timer?.invalidate()
time = 0.0
fineDustProgress = fineDustViewModel.calculatorFineDustValue(fineDustAPIData.fineDust.fineDustValue)
fineDustProgressView.progressTintColor = fineDustAPIData.fineDust.fineDustColor
timer = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(setProgress(sender:)), userInfo: nil, repeats: true)
}
@objc func setProgress(sender: Timer) {
time += 0.01
if time <= fineDustProgress{
fineDustProgressView.setProgress(time, animated: true)
}
if time > fineDustProgress {
time = 0.0
timer?.invalidate()
}
}
여기서 fineDustProgressView의 progressTintColor를 변경하고 timer를 생성한 후 생성한 timer를 통해 setProgress함수를 실행하여 progressView의 Animation을 custom 하였다.
코드상 문제가 없다고 생각했지만 위와 같은 문제가 계속 발생했다.
문제의 원인은 setProgressView()함수에서 fineDustPrgoressView의 prgoressTintColor를 변경하는 부분이었다. 이 부분을 주석처리하니 21 보다 작은 값도 제대로 나타냈다.
private func setProgressView(_ fineDustAPIData: FineDustAPIData){
timer?.invalidate()
time = 0.0
fineDustProgress = fineDustViewModel.calculatorFineDustValue(fineDustAPIData.fineDust.fineDustValue)
// 문제 원인 !!
fineDustProgressView.progressTintColor = fineDustAPIData.fineDust.fineDustColor
timer = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(setProgress(sender:)), userInfo: nil, repeats: true)
}
하지만 나는 미세먼지의 데이터를 받아와 좋음, 보통, 나쁨과 같이 세가지의 상태에 따라 progressView의 tintColor를 바꿔줘야 했다.
여러 시도를 해본 결과 configureProgressView()를 viewDidLoad()에서 실행하지 않고 setProgressView() 에서 실행시켜 문제를 해결할 수 있었다.
private func configureProgressView(){
fineDustProgressView.progressViewStyle = .bar
fineDustProgressView.trackTintColor = #colorLiteral(red: 0.835541904, green: 0.8356826901, blue: 0.8355233073, alpha: 1)
fineDustProgressView.clipsToBounds = true
fineDustProgressView.layer.cornerRadius = 15
fineDustProgressView.layer.sublayers![1].cornerRadius = 15
fineDustProgressView.subviews[1].clipsToBounds = true
fineDustProgressView.progress = 0.0
}
private func setProgressView(_ fineDustAPIData: FineDustAPIData){
timer?.invalidate()
time = 0.0
fineDustProgress = fineDustViewModel.calculatorFineDustValue(fineDustAPIData.fineDust.fineDustValue)
configureProgressView() // 여기에 추가 !!!!
fineDustProgressView.progressTintColor = fineDustAPIData.fineDust.fineDustColor
timer = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(setProgress(sender:)), userInfo: nil, repeats: true)
}
문제를 해결하였지만 configureProgressView()를 계속 호출하는건 낭비라고 생각하고 configureProgressView() 함수에 어떤 코드가 정상적인 결과를 출력하는지 찾아보았다.
찾아보니 prgoressViewStyle을 정의하는 fineDustProgressView.progressViewStyle = .bar 코드와 progressTintColor를 바꾸는 코드가 같이 호출되야 정상적인 결과를 출력하는걸 알게 되었다.
최종 코드는 아래와 같다.
override func viewDidLoad() {
super.viewDidLoad()
// configureProgressView()는 viewDidLoad에서 호출
configureProgressView()
fineDustViewModel.observable
.observe(on: MainScheduler.instance)
.subscribe(onNext:{ [weak self] in
self?.setProgressView($0)
})
.disposed(by: disposeBag)
}
private func configureProgressView(){
fineDustProgressView.trackTintColor = #colorLiteral(red: 0.835541904, green: 0.8356826901, blue: 0.8355233073, alpha: 1)
fineDustProgressView.clipsToBounds = true
fineDustProgressView.layer.cornerRadius = 15
fineDustProgressView.layer.sublayers![1].cornerRadius = 15
fineDustProgressView.subviews[1].clipsToBounds = true
fineDustProgressView.progress = 0.0
}
private func setProgressView(_ fineDustAPIData: FineDustAPIData){
timer?.invalidate()
time = 0.0
fineDustProgress = fineDustViewModel.calculatorFineDustValue(fineDustAPIData.fineDust.fineDustValue)
// progressViewStyle과 TintColor를 같이
fineDustProgressView.progressViewStyle = .bar
fineDustProgressView.progressTintColor = fineDustAPIData.fineDust.fineDustColor
timer = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(setProgress(sender:)), userInfo: nil, repeats: true)
}
여기서 주의할 점은 configureProgressView()에서 fineDustProgressView.progressViewStyle = .bar 코드는 지워주고 prgoressViewStyle은 꼭 .bar로 설정해줘야 된다.
https://stackoverflow.com/questions/54148264/uiprogressview-setprogress-issue 를 보니 나와 같은 오류가 발생하는 경우가 있어 글을 써보았지만 무엇이 제대로된 원인인지는 파악하지 못했다..😅
해결하지 못한 의문점은 이렇다 .. 아시는 분은 댓글 달아주세요 😂