Reputation: 3
I'm following https://github.com/RabbitMC/inbox-replica to make Objective-C version of inbox replica transition but I'm stuck at the code where I cannot make the Objective-C code.
Here's the Swift code:
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
let duration = transitionDuration(transitionContext)
let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
let containerView = transitionContext.containerView()
var foregroundViewController = toViewController
var backgroundViewController = fromViewController
if type == .Dismissing {
foregroundViewController = fromViewController
backgroundViewController = toViewController
}
// get target view
var targetViewController = backgroundViewController
if let navController = targetViewController as? UINavigationController {
targetViewController = navController.topViewController!
}
let targetViewMaybe = (targetViewController as? ExpandingTransitionPresentingViewController)?.expandingTransitionTargetViewForTransition(self)
And here's my Objective-C code:
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
NSTimeInterval duration = [self transitionDuration:transitionContext];
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView];
UIViewController *foregroundViewController = toViewController;
UIViewController *backgroundViewController = fromViewController;
if (type == Dismissing) {
foregroundViewController = fromViewController;
backgroundViewController = toViewController;
}
//get the target view
UIViewController *targetViewController = backgroundViewController;
if ([targetViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navController = (UINavigationController *)targetViewController;
targetViewController = navController.topViewController;
}
UIView *targetViewMaybe = ([targetViewController conformsToProtocol:@protocol(ExpandingTransitionPresentingViewController)])?[targetViewController expandingTransitionTargetViewForTransition:self]:assert(targetViewMaybe != nil);
Now the problem comes at the point where I had to call protocol method on targetViewController
which is a UIViewController
but compiler prompts me with the error:
UIViewController does not have visible interface that declares the selector 'expandingTransitionTargetViewForTransition'
Upvotes: 0
Views: 254
Reputation: 318804
The cause of the problem is that targetViewController
is of type UIViewController
. But you attempt to call a method from some protocol. The solution is to cast the pointer to the appropriate type after checking it actually conforms to the protocol.
Do yourself a favor and avoid long, hard to read and impossible to debug lines like the last one:
UIView *targetViewMaybe = ([targetViewController conformsToProtocol:@protocol(ExpandingTransitionPresentingViewController)])?[targetViewController expandingTransitionTargetViewForTransition:self]:assert(targetViewMaybe != nil);
Split it into something manageable. The following fixes the issue and makes the code much easier to read and debug:
if ([targetViewController conformsToProtocol:@protocol(ExpandingTransitionPresentingViewController)]) {
id<ExpandingTransitionPresentingViewController> controller = (id<ExpandingTransitionPresentingViewController>)targetViewController;
UIView *targetView = [controller expandingTransitionTargetViewForTransition:self];
// Do something with targetView
} else {
// Handle as needed
}
Upvotes: 1