Ich versuche, ein Steuerelement mit 3 vertikalen Schieberegler zu erstellen. Ich möchte, dass die ziehbaren Punkte auf den Schiebern Linien haben, die sie verbinden. Irgendwelche Tipps, wie man das macht?Wie erstellt man verbundene Schieberegler in Swift?
Antwort
Sie können UIBezierPath
erstellen, diesen Pfad in einem CAShapeLayer
verwenden und diese Ebene als Unterlayer zu layer
Ihrer Ansicht hinzufügen.
Das einzige Problem besteht darin, den Anfangs- und Endpunkt für Ihre Linien zu ermitteln, und zwar durch Blick auf die Schieberegler thumbRectForBounds
. Und vorausgesetzt, Sie ein Standard-UISliderView
verwendet und einfach gedreht es, sollten Sie sicherstellen, um den Punkt zu dem übergeordneten Koordinatensystem konvertieren:
class ViewController: UIViewController {
@IBOutlet weak var slider1: UISlider!
@IBOutlet weak var slider2: UISlider!
@IBOutlet weak var slider3: UISlider!
lazy var lineLayer: CAShapeLayer = {
let layer = CAShapeLayer()
layer.lineWidth = 3
layer.fillColor = UIColor.clearColor().CGColor
layer.strokeColor = UIColor.redColor().CGColor
return layer
}()
override func viewDidLoad() {
super.viewDidLoad()
[slider1, slider2, slider3].forEach { slider in
slider.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI_2))
}
view.layer.insertSublayer(lineLayer, atIndex: 0)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
lineLayer.frame = view.bounds
updatePathBetweenSliders()
}
@IBAction func didChangeValue(sender: UISlider) {
updatePathBetweenSliders()
}
private func updatePathBetweenSliders() {
let path = UIBezierPath()
path.moveToPoint(slider1.thumbCenter())
path.addLineToPoint(slider2.thumbCenter())
path.addLineToPoint(slider3.thumbCenter())
lineLayer.path = path.CGPath
}
}
Wo:
extension UISlider {
func thumbCenter() -> CGPoint {
let thumbRect = thumbRectForBounds(bounds, trackRect: trackRectForBounds(bounds), value: value)
let thumbCenter = CGPoint(x: thumbRect.midX, y: thumbRect.midY)
return convertPoint(thumbCenter, toView: superview)
}
}
Das ergibt:
Wenn Sie die Schieberegler an irgendeinem Punkt (wie ich am Ende des animierten GIF) animieren möchten, müssen Sie wahrscheinlich erneut Sortieren zu CADisplayLink
, um die Werte zu aktualisieren:
let animationDuration = 0.5
var originalValues: [Float]!
var targetValues: [Float]!
var startTime: CFAbsoluteTime!
@IBAction func didTapResetButton(sender: UIButton) {
let sliders = [slider1, slider2, slider3]
originalValues = sliders.map { $0.value }
targetValues = sliders.map { _ in Float(0.5) }
startTime = CFAbsoluteTimeGetCurrent()
let displayLink = CADisplayLink(target: self, selector: #selector(handleDisplayLink(_:)))
displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
}
func handleDisplayLink(displayLink: CADisplayLink) {
let percent = Float((CFAbsoluteTimeGetCurrent() - startTime)/animationDuration)
let sliders = [slider1, slider2, slider3]
if percent < 1 {
for (index, slider) in sliders.enumerate() {
slider.value = (targetValues[index] - originalValues[index]) * percent + originalValues[index]
}
} else {
for (index, slider) in sliders.enumerate() {
slider.value = targetValues[index]
}
displayLink.invalidate()
}
updatePathBetweenSliders()
}
Vielen Dank. Das war sehr nützlich. Ich bin neugierig - gibt es eine Möglichkeit, dies zu tun, ohne die Transform-Eigenschaft zu verwenden? Bei Transformationen wird nicht automatisch festgelegt, wodurch es schwierig wird, diese vertikalen Schieberegler sauber zu positionieren. Ich habe versucht, sie in eine Stapelansicht zu bringen, aber ich stieß auf alle möglichen Probleme, während ich versuchte, die Größe zu bekommen, die ich wollte. – kubernetes
Ich habe versucht, sie in eine Stapelansicht zu bringen und fand heraus, dass es komplizierter war, wenn Transformationen beteiligt waren. Ich habe das oben genannte mit Hilfe von transformierten Slidern mit Auto-Layout gemacht und es hat überraschend gut funktioniert (obwohl das Storyboard seltsam aussah). Sie können sicherlich auch Ihren eigenen vertikalen Schieberegler erstellen, da es nicht so kompliziert ist. Und ich bin mir sicher, dass es da draußen vertikale Schieberegler von Drittanbietern gibt, obwohl ich nicht wirklich geschaut habe und für nichts garantieren kann. – Rob
Screenshot oder Code, wo Sie das versuchen? –