web-dev-qa-db-ja.com

Swift / UIView / drawrect-必要に応じてdrawrectを更新する方法

私はSwiftを学ぶのが初めてで、信じられないほどシンプルなアプリを実行しようとしています。私がやろうとしているのは、ボタンを押したときにUIView.drawRectを更新して更新するです。アプリが最初に読み込まれたときに更新/描画され、その後は何も試みません。私は数日間これに頭を打ち続けてきましたが、何も助けが見つかりません。

私が作成した:

  • シングルビューアプリケーション

  • アクションとしてビューコントローラーにリンクされた1つのボタン

  • uIViewをサブクラス化する新しいクラスTest_View

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.")
    }

}

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")            

    }

}

(注:ボタンを押すたびにログが更新されるので、それは問題ではありません。表示が変わらないというだけです。また、ランダムな座標で四角形を描画しようとしたので、更新されているのではなく、見えないよ。)

助けてくれてありがとう!

12
Tom M

まず、UIViewの指定された初期化子を指定する必要があります(init with frame)。次に、オブジェクトのfをクラスの定数または変数(必要に応じて)にして、プロジェクトのスコープ内でアクセスできるようにします。また、ビューのサブビューとして追加する必要があります。次のようになります。

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

UIViewControllerのインスタンスではなく、Press_Button関数でインスタンス化されたTest_ViewのローカルインスタンスをsetNeedsDisplayに呼び出しています(ちなみに、ViewDidLoadでローカル変数として作成することは役に立ちません)。 @IBOutletとして作成した後、インターフェイスビルダーを使用してインスタンスを定義し、その変数にアタッチします。UIViewControllerは次のようになります。

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