アプリの高速化のため、UIViewのdraw(rect:)が呼ばれるタイミングを調べてみました。
下のように、普通に画面に貼り付ける時はdraw(rect:)が呼ばれました。
import UIKit class ViewController: UIViewController { let myView = MyView(frame: UIScreen.main.bounds) override func viewDidLoad() { super.viewDidLoad() view.addSubview(myView) } } class MyView: UIView { override func draw(_ rect: CGRect) { print("draw") } }
ちなみに貼付け後、すぐにremoveFromSuperviewをしたらdraw(rect:)は呼ばれませんでした。
view.addSubview(myView) myView.removeFromSuperview()
そのあと更にaddSubviewを呼んだ場合、draw(rect:)が1回だけ呼ばれます。
view.addSubview(myView) myView.removeFromSuperview() view.addSubview(myView)
下のように、タイミングをずらしてaddSubviewを呼んだ場合はdraw(rect:)が2回呼ばれます。
class ViewController: UIViewController { let myView = MyView(frame: UIScreen.main.bounds) override func viewDidLoad() { super.viewDidLoad() view.addSubview(myView) } override func viewDidAppear(_ animated: Bool) { myView.removeFromSuperview() view.addSubview(myView) } }
frameの値を編集した場合はdraw(rect:)は呼ばれません。
override func viewDidAppear(_ animated: Bool) { myView.frame.origin.x = 10 myView.frame.size.width = 10 myView.frame = CGRect(x: 0, y: 0, width: 100, height: 100) }
setNeedsDisplayメソッドを呼んだ時もdraw(rect:)が呼ばれます。
myView.setNeedsDisplay()
addSubviewして、直後にsetNeedsDisplayを呼んだ場合は1回だけdraw(rect:)が呼ばれます。
view.addSubview(myView) myView.setNeedsDisplay()
下のように、親ビューをremoveFromSuperviewしたりaddSubviewした時もdraw(rect:)は呼ばれました。
import UIKit class ViewController: UIViewController { let baseView = UIView(frame: UIScreen.main.bounds) let myView = MyView(frame: UIScreen.main.bounds) override func viewDidLoad() { super.viewDidLoad() baseView.addSubview(myView) view.addSubview(baseView) } override func viewDidAppear(_ animated: Bool) { baseView.removeFromSuperview() view.addSubview(baseView) } } class MyView: UIView { override func draw(_ rect: CGRect) { print("draw") } }
ただ、親ビューのsetNeedsDisplayを呼んだ時はdraw(rect:)は呼ばれませんでした。
class ViewController: UIViewController { let baseView = UIView(frame: UIScreen.main.bounds) let myView = MyView(frame: UIScreen.main.bounds) override func viewDidLoad() { super.viewDidLoad() baseView.addSubview(myView) view.addSubview(baseView) } override func viewDidAppear(_ animated: Bool) { baseView.setNeedsDisplay() } }