単純な水平のプログレスバービューを作成しようとしていますが、幅の制約を適用したいと思います。カスタムプログレスバーの幅の制約を自動調整するAutolayout
テスト目的で、タップするとプログレスバーの割合が増加するボタンを作成しました。
ボタンをタップすると、幅の制約が期待どおりにアニメーション化されます。ただし、コンポーネントを初期化するとすぐにパーセンテージを設定しようとすると、ビュー全体がアニメーション化されますが、これは私が望むものではありません。
class ProgressBar: UIView {
private let progressView: UIView
private var progressBarWidth: NSLayoutConstraint? = nil
var percentage: Double = 0 {
didSet {
updateProgress()
}
}
init() {
progressView = UIView()
super.init(frame: .zero)
setupBackgroundBar()
setupProgressView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupBackgroundBar() {
self.heightAnchor.constraint(equalToConstant: 10).isActive = true
self.backgroundColor = UIColor(colorLiteralRed: 1, green: 1, blue: 1, alpha: 0.5)
}
private func setupProgressView(){
self.addSubview(progressView)
progressView.translatesAutoresizingMaskIntoConstraints = false
progressView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
progressView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
progressView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
progressView.backgroundColor = UIColor.white
}
func updateProgress() {
let progressMultiplier = CGFloat(percentage/100)
UIView.animate(withDuration: 1.0) {
if let progressConstraint = self.progressBarWidth {
NSLayoutConstraint.deactivate([progressConstraint])
}
self.progressBarWidth = self.progressView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: progressMultiplier)
self.progressBarWidth?.isActive = true
self.layoutIfNeeded()
}
}
}
ビューコントローラ
class ViewController: UIViewController {
let progressBar: ProgressBar
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.black
self.view.addSubview(progressBar)
progressBar.translatesAutoresizingMaskIntoConstraints = false
progressBar.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 30).isActive = true
progressBar.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 30).isActive = true
progressBar.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -30).isActive = true
let button = UIButton(type: .roundedRect)
self.view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = UIColor.white
button.setTitleColor(UIColor.black, for: .normal)
button.setTitle("Increase 1%", for: .normal)
button.topAnchor.constraint(equalTo: progressBar.bottomAnchor, constant: 10).isActive = true
button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
button.addTarget(self, action:#selector(self.buttonTapped), for: .touchUpInside)
}
required init?(coder aDecoder: NSCoder) {
progressBar = ProgressBar()
super.init(coder: aDecoder)
}
func buttonTapped() {
progressBar.percentage += 1
}
}
私は私がボタンをタップしたときにそれが起こると同じように、ビューを初期化するとすぐに幅の制約をアニメーション化したいと思います。
strokeHegEnd propertysでstrokeBeginを使用してCAShapeLayerを試しましたか?私はこれを行うための最良のアプローチだと思います –