2017-06-26 5 views
0

Ich habe eine iOS 10 App, die eine Schaltfläche ("Press Me!") Enthält, und eine UIView, die ein blau umrandetes Rechteck ohne Füllung enthält. Ich möchte das Rechteck allmählich (in etwa 5 Sekunden) mit Rot füllen, indem ich eine beliebige Methode benutze (ich habe es mit UIView.animation(withDuration:, animations:) versucht). Ich werde den Code unten enthalten:Füllen Sie allmählich eine Form mit swift und UIViewAnimation?

Hier ist der Viewcontroller:

class ViewController: UIViewController { 

@IBOutlet weak var tronkyy: tronc! 

override func viewDidLoad() { 
    super.viewDidLoad() 

} 

@IBAction func didPress(_ sender: UIButton) { 
    tronkyy.full = true 
    tronkyy.setNeedsDisplay() 
} } 

und die Aussicht:

@IBDesignable class tronc: UIView { 

//var value = 0.0 
var full = false 

override func draw(_ rect: CGRect) { 
    UIColor.blue.setStroke() 
    boxPath().stroke() 
    drawDynamic() 
} 

private func boxPath() -> UIBezierPath { 
    let path = UIBezierPath(rect: CGRect(x: 0.1 * frame.width, y: 0.1 * frame.height, width: 0.8 * frame.width, height: 0.8 * frame.height)) 
    UIColor.blue.setStroke() 
    return path 
} 

func drawDynamic() { 
    if full { 
     UIView.animate(withDuration: 10) { _ in 
      //while self.value < 1 { 
       let path = UIBezierPath(rect: CGRect(x: 0.1 * self.frame.width, y: 0.1 * self.frame.height, width: (0.8 * self.frame.width), height: 0.8 * self.frame.height)) //* CGFloat(value))) 
       UIColor.red.setFill() 
       path.fill() 

       //self.value += 0.1 
      //} 
     } 
     full = false 
    } 
} } 

Ah, und ja, ignorieren Sie bitte, dass die rote Ansicht das Rechteck abzudecken. Das Problem ist, dass es keine allmähliche Füllung gibt. es füllt es nur ein für allemal.

Edit: Ich habe die "Wert" -Eigenschaft und die While-Schleife auskommentiert, wie in den Antworten vorgeschlagen, aber es funktioniert immer noch nicht.

+0

Können Sie eine UIView mit einer Unteransicht verwenden? Oder planen Sie eine komplexere Form? – DonMag

+0

Ich plane eigentlich komplexe Dinge zu verwenden. Aber ich werde mich freuen, deinen Weg zu sehen –

Antwort

1

Dies ist ein Ansatz mit einer Ansicht mit einer Unteransicht. Für eine komplexere Form als ein Rechteck könnte dies mit Masken geschehen.

Sie können diese direkt auf einem Spielplatz Seite laufen:

import UIKit 
import PlaygroundSupport 

class TestViewController : UIViewController { 

    let btn: UIButton = { 
     let b = UIButton() 
     b.setTitle("Tap Me", for: .normal) 
     b.backgroundColor = .blue 
     b.frame = CGRect(x: 20, y: 20, width: 200, height: 30) 
     return b 
    }() 

    let blueRect: UIView = { 
     let v = UIView() 
     v.layer.borderColor = UIColor.blue.cgColor 
     v.layer.borderWidth = 2.0 
     v.backgroundColor = .clear 
     v.translatesAutoresizingMaskIntoConstraints = false 
     return v 
    }() 

    let redRect: UIView = { 
     let v = UIView() 
     v.backgroundColor = .red 
     v.translatesAutoresizingMaskIntoConstraints = false 
     return v 
    }() 

    var redRectHeightConstraint: NSLayoutConstraint? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.view.addSubview(btn) 

     btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside) 


     blueRect.addSubview(redRect) 
     self.view.addSubview(blueRect) 

     redRect.leftAnchor.constraint(equalTo: blueRect.leftAnchor, constant: 0.0).isActive = true 
     redRect.rightAnchor.constraint(equalTo: blueRect.rightAnchor, constant: 0.0).isActive = true 
     redRect.bottomAnchor.constraint(equalTo: blueRect.bottomAnchor, constant: 0.0).isActive = true 

     redRectHeightConstraint = NSLayoutConstraint(item: redRect, 
                attribute: .height, 
                relatedBy: .equal, 
                toItem: nil, 
                attribute: .notAnAttribute, 
                multiplier: 1.0, 
                constant: 0.0) 

     redRect.addConstraint(redRectHeightConstraint!) 

     blueRect.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.5).isActive = true 
     blueRect.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.5).isActive = true 
     blueRect.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true 
     blueRect.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true 

    } 

    func didTap(_ sender: Any?) -> Void { 
     UIView.animate(withDuration: 5.0, animations: { 
      _ in 
      self.redRectHeightConstraint!.constant = self.blueRect.frame.size.height 
      self.view.setNeedsLayout() 
     }, completion: { 
      finished in 
     }) 

    } 

} 


let vc = TestViewController() 
vc.view.backgroundColor = .yellow 
vc.view.frame = CGRect(x: 0, y: 0, width: 600, height: 600) 

PlaygroundPage.current.liveView = vc 

Hinweis: dies nur wird probieren, Demonstration Code ... ein copy/paste-Lösung sein, nicht gemeint.

0

Sie sollten keine while-Schleife in einer Animationsfunktion verwenden. Versuchen Sie diese Version

UIView.animate(withDuration: 10) { _ in 
    let path = UIBezierPath(rect: CGRect(x: 0.1 * self.frame.width, y: 0.1 * self.frame.height, width: (0.8 * self.frame.width), height: 0.8 * self.frame.height)) 
    UIColor.red.setFill() 
    path.fill() 
} 
+0

Es hat nicht funktioniert :(Aber ich werde den Loop-Code in der Frage –

+0

@FayezHellani kommentieren Sie sehen immer noch, dass rote Farbe sofort gefüllt werden? –

+0

Ja, es tut es immer noch –

Verwandte Themen