My top level UIView
contains a some labels and a drawing canvas. The drawing canvas is itself a UIView
which overrides its drawRect()
method and, of course, the various touch methods. When the user has finished drawing, I want to update one or more labels that are outside the canvas (i.e. are all components of the top level UIView
).
What's the best way to do it?
I currently have the top level UIViewController
pass the various labels into my CanvasView
s from the top level viewDidLoad()
method and I store them locally. Whenever I need to update a label, I do so from the local copies of these sibling views I have - But I'm not happy with this because it feels kludgy.
To explain further, this is what I do in my top level UIViewController
:
@IBOutlet weak var myLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
for v in self.view.subviews {
if v .isKindOfClass(CanvasView) {
let canvasView = v as CanvasView
canvasView.setMyLabel(myLabel)
}
}
}
And then in my CanvasView.swift
file, I have:
private var myLabel: UILabel!
...
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
// do stuff ...
setNeedsDisplay()
myLabel.text = "etc.etc."
}
Is there a better way?
Thanks.
Ave
I would implement the delegate pattern. When creating the canvas pass the parent viewcontroller where you can implement various callback methods.
Here you can find a more detailed explanation of the various methods of implementing a delegate. Some of them might be overkill for this single and simple usecase.
Example: you have a game insance (called game), which defines a delegate protocol. the protocol contains several methods for different events. (e.g.
-(void)gameDidFinish
etc.)Now the game implements a method
addDelegate
which is called by every instance, which wants to be notified for certain events of the game. All of these instances, who register themselves as delegates implement all or some of the methods defined in the games protocolIf one of the game events is triggered the game checks all of its registered delegates if they have implemented the corresponding method and calls it.
Important: as mentioned the protocol ma be overkill, as you have only one delegate.
If your canvas is a separate
viewController
, you can use delegate protocols to access your base view controller from the canvas view controller. Suppose you have aBaseViewController
which calls thecanvasViewController
.In your
canvasViewController.h
add the following :Now from your
canvasViewController.m
file execute this code whenever you want to update your labels (or ask the baseViewController to do something) :Now for your base view controller to accept messages from the canvas, the BaseVC has to "adopt" the
CanvasDelegate
Protocol and also implement the required methods. InbaseViewController.h
, add the following :In
baseViewController.m
when you create an object of canvasViewController for pushing, add the following command :And don't forget to implement the required methods in
baseViewController.m
like so :