Un-Wire an event from being called - ios

How can I unwire a function so it doesn't get called?
//Wire an event
myScrollView.delegate = self
... do something
// How can I unwire it so the scrollview functions dont get called?

Simply set the delegate property to nil if you no longer wish to have any of the delegate methods called.

Related

Method tableView.reloadData() asynchronous execution

My code:
...
self.tableView.reloadData()
self.someOldValue = self.someNewValue
...
TableView delegate and datasource methods work with self.someOldValue. I need use self.someOldValue in those methods before it changes. How to do it? Method reloadData() works asynchronous and tableView delegate and datasource methods works with newValue already(self.someOldValue = self.someNewValue executes before self.tableView.reloadData())

Calling reloadData through delegate

I have a table view which conforms to custom protocol FoodItemProtocol and it implements its funciton:
func foodItemWasTaggedAsFavorite() {
tableView?.reloadData()
print("foodItemWasTaggedAsFavorite")
}
After foodItem is tagged as favorite, this function is called and print statement is executed, however table view is never reloaded.
I realized I don't actually need to use delegation for this, it works fine if I call to reloadData() in viewDidAppear(). But still I'd like to know why it's not working through delegation? I've even tried to call reloadData() on main thread like this:
dispatch_async(dispatch_get_main_queue()) {
tableView?.reloadData()
}
But I got same result.
If you are calling the delegate method from a different view controller, tableView will be nil.
To check this, modify foodItemWasTaggedAsFavorite to be:
if let tableView = tableView {
tableView.reloadData()
print("foodItemWasTaggedAsFavorite")
}
Now check if the print statement is being printed. I'm pretty sure it won't, because tableView is nil.
However, in viewDidAppear:, the table view has already been loaded, so it isn't nil.
Also, there is no reason to reload the data if the table view isn't on screen anyways.

Swift, how to tell a controller that another controller is its delegate

I'm learning Swift and I'm studying the delegation pattern.
I think I understand exactly what is delegation and how it works, but I have a question.
I have a situation where Controller A is the delegate for Controller B.
In controller B I define a delegate protocol.
In controller B I set a variable delegate (optional)
In controller B I send message when something happens to the delegate
Controller A must adopt method of my protocol to become a delegate
I cannot understand if every delegate controller (in this case A) listens for messages sent by controller B or If I have to tell to controller B that A is now his delegate.
I notice that someone use this code (in controller A)
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Example" {
let navigationController = segue.destinationViewController as UINavigationController
let controller = navigationController.topViewController as AddItemViewController
controller.delegate = self
}
}
Is this the only way to tell a delegator who is his delegate?
I believe, you need to tell a deligator who is its delegate upon creation of that it. Now, the delegator can be created programatically or through storyboard. So, based on that you have two options, you can tell it who is its delegator programatically like you showed in the code or from IB.
The key here is upon creation. Let's me explain myself. Take the case of a UIView. Say, you want a Custom UIView object(CustomView). So, you drag and drop a UIView in your View Controller and in the identity inspector, you assign its class as of your CustomView's class. So, basically, as soon as the controller is created, your custom view will also be created. Now, you can either say it that the View Controller in which it is created is its delegate or You can go to the IB and connect the view's delegate to the View Controller.
Now, let's assume that you wanted the custom view to be created in your ViewController programatically. In that case, you would probably call the -initWithFrame: method to create the view and upon creation you tell that delegator that who is its delegate like-
myCustomView.delegate = self;
same goes with a View Controller.
controller.delegate = self;
So, basically to tell a delegator who is its delegate, you first need that delegator to be created. At least, that's what I think.
I think one of the best example of delegation is UITableView.
Whenever you want the control of various properties of a tableView e.g. rowHeight etc, you set your controller to be the delegate of your tableview. To set the delegate of your tableView you need to have tableView created obviously as pointed out by #natasha.
So in your case, you can set delegate of your delegator when you create it or when you find a need for the controller to be delegate of your delegator but you definitely need your delegator to be present to set its property.
You can set your controller as delegate at any time when you require control.
I'm sure you want your UIViewController to act like described, but here is a simpler example how to use the delegation pattern with custom classes:
protocol ControllerBDelegate: class {
func somethingHappendInControllerB(value: String)
/* not optional here and passes a value from B to A*/
/* forces you to implement the function */
}
class ControllerB {
var delegate: ControllerBDelegate?
private func someFunctionThatDoSomethingWhenThisControllerIsAlive() {
/* did some magic here and now I want to tell it to my delegate */
self.delegate?.somethingHappendInControllerB(value: "hey there, I'm a magician")
}
func doSomething() {
/* do something here */
self.someFunctionThatDoSomethingWhenThisControllerIsAlive()
/* call the function so the magic can really happen in this example */
}
}
class ControllerA: ControllerBDelegate {
let controllerB = ControllerB()
init() {
self.controllerB.delegate = self /* lets say we add here our delegate*/
self.controllerB.doSomething() /* tell your controller B to do something */
}
func somethingHappendInControllerB(value: String) {
print(value) /* should print "hey there, I'm a magician" */
}
}
I wrote the code from my mind and not testet it yet, but you should get the idea how to use such a pattern.

Swift : Override method drawInContext of CALayer not beeing called after setNeedsDisplay

The control as 3 custom layers and is something like this:
class BASwitch: UIControl {
override init(frame:CGRect){
super.init(frame:frame)
...
self.toggleLayer = BASwitchToggleLayer()
self.layer.addSublayer(self.toggleLayer)
self.toggleLayer.setNeedsDisplay()
...
}
}
When the toggleLayer is changed inside an selector invoked from UIViewControl the drawInContext is called and the content of toggleLayer is updated.
When the toggleLayer is invoked from inside an render delegate method (renderer from SCNSceneRendererDelegate) the drawInContext method is not called.
In both situations the update to the layer is perform in the same way by this code:
self.toggleLayer.offString = newValue
self.toggleLayer.setNeedsDisplay()
Have Swift something like doEvents() of C# windows forms that needs to be called?
Can't figure out if is this the problem or any other way to force the update.

Objective-C calling upon a IBAction without having to change the sender to nil

I have a program that I would like to call upon another IBAction in a IBAction. However, the way I got it to work used [self buttonPress:nil]; which called upon the IBAction button as though it was a function but the problem was that the IBAction that I called upon sender's instance turned to nil so if anything in the IBAction that was called upon used sender it simply wouldn't do anything. Is there a way to call a IBAction without changing the instance of the sender?
A potential workaround "could" be to have your #IBAction methods serve as wrapper around different methods. That way when you want to call another #IBAction you are actually calling the method it wraps.
#IBACTION Function1 {
// Calls method:
subMethod1()
}
#IBACTION Function2 {
// Calls method:
subMethod2()
}
#IBACTION Function3 {
// Calls method:
subMethod1()
subMethod2()
}

Resources