Ios setNeedsDisplay()未调用draw(rect:CGRect)

Ios setNeedsDisplay()未调用draw(rect:CGRect),ios,swift,Ios,Swift,我在这个网站上发现了类似的问题,但没有一个能解决我的问题。请仔细阅读整个代码。当我想在MyView上画一条线时,setNeedsDisplay函数没有调用draw_urect:CGRect 我在storyboard中创建了一个名为myView的视图作为MyViewController的子视图,并创建了视图控制器的IBOutlet 然后我创建了一个名为MyViewClass的类,并将其设置为storyboard中myView的类 我将布尔值drawLine设置为true并调用函数updateLin

我在这个网站上发现了类似的问题,但没有一个能解决我的问题。请仔细阅读整个代码。当我想在MyView上画一条线时,setNeedsDisplay函数没有调用draw_urect:CGRect

我在storyboard中创建了一个名为myView的视图作为MyViewController的子视图,并创建了视图控制器的IBOutlet

然后我创建了一个名为MyViewClass的类,并将其设置为storyboard中myView的类

我将布尔值drawLine设置为true并调用函数updateLine, 问题是SetNeedsDisplay没有触发draw_rect:CGRect函数

import UIKit

class MyViewClass : UIView{

    var drawLine = Bool() // decides whether to draw the line
    func updateLine(){
        setNeedsDisplay()
    }
    override func draw(_ rect: CGRect) {
        if drawLine == true{
            guard let context = UIGraphicsGetCurrentContext() else{
                return
            }
            context.setLineWidth(4.0)
            context.setStrokeColor(UIColor.red.cgColor)
            context.move(to: CGPoint(x: 415 , y: 650))
            context.addLine(to: CGPoint(x:415 , y: 550))
            context.strokePath()
        }

    }
}
class myViewController:UIViewController {
    @IBOutlet weak var insideView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()


        // Do any additional setup after loading the view.
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let myViewInstance = MyViewClass()
        myViewInstance.drawLine = true
        myViewInstance.updateLine()
    }
}
我对斯威夫特相当陌生。任何帮助都将不胜感激。谢谢。

MyView课程

class myView : UIView {
    var updateView : Bool = false {
        didSet {
            setNeedsDisplay()
        }
    }

    override func draw(_ rect: CGRect) {
        print("in Draw")

    }

}
MyViewController

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let view = myView()
        view.updateView = true
    }
}
在故事板中,我将视图类设置为myView,因此它是可见的

希望这能对您有所帮助。

您有两个问题:

您没有为新视图提供框架,因此它默认为零宽度和零高度 您没有将视图添加到视图继承权

let myViewInstance = MyViewClass(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height))
myViewInstance.backgroundColor = .white  // you might want this a well
myViewInstance.drawLine = true
self.view.addSubview(myViewInstance)
myViewInstance.updateLine()
更改特性(如drawLine)时,让视图重新绘制的更简洁的方法是使用特性观察者:

var drawLine: Bool = true {
    didSet {
        setNeedsDisplay()
    }
}
这样,当您更改属性时,视图将自动重新绘制,而不需要updateLine

请注意,setNeedsDisplay只是安排视图进行重画。如果在每个属性上设置此选项,则即使更改了多个属性,视图也只会重新绘制一次


注意:viewDidLoad是添加行的更合适的位置,因为创建视图时只调用一次。视图将在视图出现时被调用,因此可以多次调用。例如,在UITabView中,每当用户切换到该选项卡时,都会调用ViewWillDisplay。

请查看此项。我自己也尝试过,感觉如果视图不可见,就不会调用drawRect。只需确认在将绘制线布尔设置为true时,您计划更新的视图是可见的。该视图从未添加到视图层次结构中,因此它将永远不会被绘制。您能告诉我如何将其添加到视图层次结构中吗?我是否只将视图添加到主视图中?因为我已经这么做了。谢谢你详尽的回答,我是否需要对这个观点做出解释?或者我可以将子视图添加到这个视图类的实例中吗?@JohnXavier我还没有发布视图。Thangs@chirag90,你的答案也是正确的,谢谢你。谢谢@vacawama,这解决了我的问题。非常感谢。