Невозможно получить доступ к фрейму uiview после настройки его макета.Рамка и центр задаются как 0,0 баллов.
Я должен также упомянуть, что в этом проекте нет раскадровок.Все представления и все создаются программно.
Я программно создал UIView resultView
и добавил его как подпредставление в scrollView
, которое также добавлено как подпредставление view
, затем установил его ограниченияЯкоря в методе с именем setupLayout()
Я вызываю setupLayout()
в viewDidLoad()
, а после этого метода я вызываю другой метод с именем configureShapeLayer()
.Внутри configureShapeLayer()
я пытаюсь получить доступ к центру моего вида как:
let center = resultView.center // should give resultView's center but gives 0
Затем, используя это значение центра, я пытаюсь добавить два bezierPaths, чтобы иметь вид строки состояния.Но поскольку центр resultView не обновляется в этот момент, он выглядит как неуместное.Пожалуйста, смотрите картинку ниже:
Я также пытался позвонить setupLayout()
в loadView()
, затем позвонить configureShapeLayer()
в viewDidLoad()
, но ничего не изменилось.
Поэтому мне нужен способ убедиться, что все представления установлены в моем представлении, все ограничения и макеты применяются перед вызовом configureShapeLayer()
.Но как я могу это сделать?
Я также пытался вызвать configureShapeLayer()
в обоих методах viewWillLayoutSubviews()
и viewDidLayoutSubviews()
, но это ухудшило ситуацию и не работало.
Whole View ControllerФайл приведен ниже: Сначала объявляются представления, затем они добавляются в представление в prepareUI()
, в конце prepareUI()
вызывается другой метод setupLayout()
.После завершения настройки макета, как видно из viewDidLoad, наконец, вызывается метод configureShapeLayer()
.
import UIKit
class TryViewController: UIViewController {
let score: CGFloat = 70
lazy var percentage: CGFloat = {
return score / 100
}()
// MARK: View Declarations
private let scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.backgroundColor = .white
return scrollView
}()
private let iconImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
return imageView
}()
let scoreLayer = CAShapeLayer()
let trackLayer = CAShapeLayer()
let percentageLabel: UILabel = {
let label = UILabel()
label.text = ""
label.textAlignment = .center
label.font = TextStyle.systemFont(ofSize: 50.0)
return label
}()
// This one is the one should have status bar at center.
private let resultView: UIView = {
let view = UIView()
view.backgroundColor = .purple
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
prepareUI()
configureShapeLayer()
}
private func prepareUI() {
resultView.addSubviews(views: percentageLabel)
scrollView.addSubviews(views: iconImageView,
resultView)
view.addSubviews(views: scrollView)
setupLayout()
}
private func setupLayout() {
scrollView.fillSuperview()
iconImageView.anchor(top: scrollView.topAnchor,
padding: .init(topPadding: 26.0))
iconImageView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, multiplier: 0.31).isActive = true
iconImageView.heightAnchor.constraint(equalTo: iconImageView.widthAnchor, multiplier: 0.67).isActive = true
iconImageView.anchorCenterXToSuperview()
//percentageLabel.frame = CGRect(x: 0, y: 0, width: 105, height: 60)
//percentageLabel.center = resultView.center
percentageLabel.anchorCenterXToSuperview()
percentageLabel.anchorCenterYToSuperview()
let resultViewTopConstraintRatio: CGFloat = 0.104
resultView.anchor(top: iconImageView.bottomAnchor,
padding: .init(topPadding: (view.frame.height * resultViewTopConstraintRatio)))
resultView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, multiplier: 0.533).isActive = true
resultView.heightAnchor.constraint(equalTo: resultView.widthAnchor, multiplier: 1.0).isActive = true
resultView.anchorCenterXToSuperview()
configureShapeLayer()
}
private func configureShapeLayer() {
let endAngle = ((2 * percentage) * CGFloat.pi) - CGFloat.pi / 2
let center = resultView.center // should give resultView's center but gives 0
// Track Layer Part
let trackPath = UIBezierPath(arcCenter: center, radius: 50, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)
trackLayer.path = trackPath.cgPath
trackLayer.strokeColor = UIColor.lightGray.cgColor // to make different
trackLayer.lineWidth = 10
trackLayer.fillColor = UIColor.clear.cgColor
trackLayer.lineCap = .round
resultView.layer.addSublayer(trackLayer)
// Score Fill Part
let scorePath = UIBezierPath(arcCenter: center, radius: 50, startAngle: -CGFloat.pi / 2, endAngle: endAngle, clockwise: true)
scoreLayer.path = scorePath.cgPath
scoreLayer.strokeColor = UIColor.red.cgColor
scoreLayer.lineWidth = 10
scoreLayer.fillColor = UIColor.clear.cgColor
scoreLayer.lineCap = .round
scoreLayer.strokeEnd = 0
resultView.layer.addSublayer(scoreLayer)
}
}