Reputation: 2902
I have a UIStoryboardSegue
subclass for replacing current view controller with next view controller.
As we have a Animates
property in interface editor, I want to access this property in the subclass.
My code is following:
class ReplaceSegue: UIStoryboardSegue {
override func perform() {
var viewControllers = source.navigationController?.viewControllers.dropLast() ?? []
viewControllers.append(destination)
source.navigationController?.setViewControllers(viewControllers.map {$0}, animated: true) // I dont want this `true` to be hardcoded
}
}
Upvotes: 1
Views: 303
Reputation: 30719
You shouldn't need a UIStoryboardSegue
subclass for this. The docs state "You can subclass UIStoryboardSegue
in situations where you want to provide a custom transition between view controllers". This means that a replacement without without any animation isn't a custom transition, thus shouldn't use a segue subclass.
The correct way to do replacement is to use a Show Detail (e.g. Replace) segue and inside the parent view controller that is managing the child view controllers implement the method showDetailViewController
and replace the children, e.g.
@implementation DetailNavigationController
- (void)showDetailViewController:(UIViewController *)vc sender:(id)sender{
[self setViewControllers:@[vc] animated:NO];
}
If you didn't know, the Show Detail segue (after magically instantiating the destination view controller) has a perform method that just calls showDetailViewController
on self, and the base UIViewController
implementation searches up the view controller hierarchy looking for one that overrides showDetailViewController
, so you can intercept it and perform your custom code, before say it goes up to another parent that might implement it also like a split view.
Upvotes: 0
Reputation: 20379
As per comments in UIStoryBoardSegue
class
The segue runtime will call +[UIView setAnimationsAreEnabled:] prior to invoking this method, based on the value of the Animates checkbox in the Properties Inspector for the segue.
So obviously you can read the value of animate check box by using
UIView.areAnimationsEnabled
So in my custom segue
class MySegue: UIStoryboardSegue {
override func perform() {
debugPrint(UIView.areAnimationsEnabled)
}
}
This prints false
if animate checkbox is unchecked
or true
if it is checked
:)
So in your case
class ReplaceSegue: UIStoryboardSegue {
override func perform() {
var viewControllers = source.navigationController?.viewControllers.dropLast() ?? []
viewControllers.append(destination)
source.navigationController?.setViewControllers(viewControllers.map {$0}, animated: UIView.areAnimationsEnabled)
}
}
I hope whats happening is already clear, incase you still have doubt, here is the explanation, iOS checks the animates checkbox value and uses it to set whether animations are enabled or not by calling setAnimationsAreEnabled
with the value of animates check box in interface prior to calling perform()
method.
So when the control reaches inside perform you can be assured that iOS has already read the value of animates check box and used it to set setAnimationsAreEnabled
all you have to do now is to ask areAnimationsEnabled
to get the value of animates check box.
So that should provide you the value of animates checkbox :)
Hope it helps :)
Upvotes: 1