2016-08-04 12 views
0

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?

+0

Screenshot oder Code, wo Sie das versuchen? –

Antwort

1

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:

lines between sliders

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() 
} 
+0

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

+0

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