私は、離散ポイントを持つスライダーに作成しようとしているxibを持つUIViewサブクラスを持っています。カスタムスライダーとオートレイアウトの問題
私は「トラック」と「親指」を持っています。トラックに沿って、4つの円が均等に配置されていて、親がドラッグされているときにスナップすることができます。
私が使用しているコードは以下の通りです:
override func awakeFromNib() {
// Layout circles
for index in stride(from: numberOfCircles, to: 0, by: -1) {
let xValue = (((index - 1)/(numberOfCircles - 1))*track.frame.size.width) - circleSize/2 + thumbWidth.constant/2
makeCircle(withXValue: xValue)
}
}
fileprivate func makeCircle(withXValue xValue: CGFloat) {
let circle = CAShapeLayer()
circle.path = UIBezierPath(ovalIn: CGRect(x: xValue , y: self.frame.height/2 - circleSize/2, width: circleSize, height: circleSize)).cgPath
circle.fillColor = UIColor(red: 238/255, green: 79/255, blue: 84/255, alpha: 1).cgColor
self.layer.addSublayer(circle)
}
私はこれが仕事だと思う、しかし、track.frame.size.width
が正しくありません。これは、このUIView
サブクラスを別のビューに追加し、autolayoutを使用してその幅を設定するためです。 awakeFromNib()
に返す幅は、xibの値です。 この問題を解決するためにトラックの実際の幅をどのように得ることができますか?フレームが変更された場合、あなたがそれらにアクセスできるようにプロパティに、あなたのサークルの層を保存
circle.position = CGPoint(x: xValue , y: self.frame.height/2 - circleSize/2)
:
'と、それが唯一の二度目' layoutSubviews(呼び出されることを確認してください:オーバーライドメソッド
layoutSublayers(of layer: CALayer)
は、新しいフレームの値を使用して位置を設定するにはそれが動作します。しかし、それは少しハッキリのようです。 – Tometoyou'layoutSubviews()'を試してください。ただし、複数回呼び出される可能性があります。編集:ちょうどあなたのコメントを見た - はい、少し粘り気ですが、最高の方法。 (それがビューコントローラの場合は、より良いオプションがあります。) – dfd