Reputation: 73
I found similar questions in this website but none of them solved my issue. Please carefully read the whole code. The setNeedsDisplay()
function is not calling the draw(_ rect: CGRect)
when I want to draw a line on MyView.
I created a view called "myView" in storyboard as sub View of "MyViewController" and created a IBOutlet
to the view controller.
Then I created a class called "MyViewClass" and set it as the class of "myView" in storyboard.
I set the bool value drawLine to true and call function updateLine()
,
the problem is the setNeedsDispaly()
is not triggering the draw(_ rect: CGRect)
function.
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()
}
}
I'm fairly new to Swift. Any help will appreciated. Thanks.
Upvotes: 1
Views: 1760
Reputation: 154691
You have 2 issues:
frame
so it defaults to zero width and zero heightyou're not adding the view to the view heirarchy
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()
A cleaner way to have your view redraw when a property (such as drawLine
) is changed is to use a property observer:
var drawLine: Bool = true {
didSet {
setNeedsDisplay()
}
}
That way, the view will automatically redraw when you change a property and then you don't need updateLine()
.
Note that setNeedsDisplay
just schedules the view for redrawing. If you set this on every property, the view will only redraw once even if multiple properties are changed.
Note: viewDidLoad()
would be a more appropriate place to add your line because it is only called once when the view
is created. viewWillAppear()
is called anytime the view
appears so it can be called multiple times (for instance in a UITabView
, viewWillAppear()
is called every time the user switches to that tab).
Upvotes: 2
Reputation: 2240
MyView class
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
}
}
In the storyboard i had setup the view class as myView therefore its visible.
Hopefully this will help you.
Upvotes: 0