web-dev-qa-db-fra.com

Swift / UIView / drawrect - comment obtenir drawrect à mettre à jour en cas de besoin

Je suis nouveau dans l'apprentissage de Swift et j'essaie de faire fonctionner une application incroyablement simple. Tout ce que j'essaie de faire est obtenir UIView.drawRect pour mettre à jour lorsque j'appuie sur un bouton. Il met à jour/dessine lorsque l'application se charge pour la première fois, puis rien après, quoi que j'essaie. Je me bats la tête contre ça depuis quelques jours, et rien de ce que je peux trouver ne m'aide.

j'ai créé:

  • application à vue unique

  • un bouton, lié pour voir le contrôleur comme une action

  • une nouvelle classe, Test_View, sous-classe UIView

Code ViewController:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        var f = Test_View()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func Button_Pressed(sender: AnyObject) {
        var f = Test_View()
        f.setNeedsDisplay()
        NSLog("Button pressed.")
    }

}

Code Test_View:

class Test_View: UIView {

    override func drawRect(rect: CGRect) {
        let h = rect.height
        let w = rect.width
        var color:UIColor = UIColor.yellowColor()

        var drect = CGRect(x: (w * 0.25),y: (h * 0.25),width: (w * 0.5),height: (h * 0.5))
        var bpath:UIBezierPath = UIBezierPath(rect: drect)

        color.set()
        bpath.stroke()

        NSLog("drawRect has updated the view")            

    }

}

(Remarque: le journal est mis à jour chaque fois que j'appuie sur le bouton, ce n'est donc pas le problème. C'est juste que l'affichage ne change jamais. De plus, j'ai essayé de dessiner le rectangle avec des coordonnées aléatoires, donc ce n'est pas qu'il se met à jour mais je '' je ne le vois pas.)

Merci pour toute aide!

12
Tom M

Tout d'abord, vous devez spécifier un initialiseur désigné pour UIView (init avec trame). Faites ensuite de votre objet f une constante ou une variable de classe (selon vos besoins) afin qu'il soit accessible dans le cadre du projet. Vous devez également l'ajouter en tant que sous-vue de votre vue. Cela ressemble à ceci:

import UIKit

class ViewController: UIViewController {
    let f = Test_View(frame: CGRectMake(0, 0, 50, 50))

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(f)
    }

    @IBAction func buttonPressed(sender: UIButton) {
        f.setNeedsDisplay()
    }
}

class Test_View: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {
        let h = rect.height
        let w = rect.width
        let color:UIColor = UIColor.yellow

        let drect = CGRect(x: (w * 0.25),y: (h * 0.25),width: (w * 0.5),height: (h * 0.5))
        let bpath:UIBezierPath = UIBezierPath(rect: drect)

        color.set()
        bpath.stroke()

        NSLog("drawRect has updated the view")

    }

}
18
Ian

Vous appelez setNeedsDisplay une instance locale de Test_View instanciée dans la fonction Press_Button, pas une en vous UIViewController (que vous devez faire en passant, la créer en tant que variable locale dans ViewDidLoad ne vous sert à rien). Vous pouvez le créer en tant que @IBOutlet, puis utiliser le générateur d'interface pour définir une instance à attacher à cette variable - UIViewController se présente comme suit:

class ViewController: UIViewController {
    @IBOutlet weak var instruction: UILabel?
    @IBOutlet weak var f: Test_View?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func Button_Pressed(sender: AnyObject) {
        f.setNeedsDisplay()
        NSLog("Button pressed.")
    }

    ...
3
Ron