Skip to content

Instantly share code, notes, and snippets.

@AndyDentFree
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndyDentFree/8e89cb4ca678d3d0bcea to your computer and use it in GitHub Desktop.
Save AndyDentFree/8e89cb4ca678d3d0bcea to your computer and use it in GitHub Desktop.
Using Objective-C++ for type-safe walking up parent views
/*
Sometimes in iOS code, you need to be able to walk up the chain of parent views, especially if working on legacy code.
This has been hardcoded in the past with horrible assumptions like this, which broke again in iOS 8:
if (IS_IOS7_AND_UP) {
spdVC = (SuperDuperViewController*)[(UITableView*)self.superview.superview.superview.superview.superview delegate];
} else {
spdVC = (SuperDuperViewController*)[(UITableView*)self.superview.superview.superview delegate];
}
Usage ONLY IN A .mm FILE eg:
UITableView* parentTable = safeParent<UITableView>(self);
or, for a UITableView delegate
SuperDuperViewController* spdVC = safeParentDelegate<SuperDuperViewController>(self);
if (spdVC) {...}
If you have never heard of Objective-C++ it allows you to use C++ within Objective-C code
so you can use templates like the following.
*/
template <class ultimateParentViewT>
ultimateParentViewT* safeParent(UIView* ofView)
{
if (ofView == nil)
return nil;
UIView* parent = ofView.superview;
if (!parent)
return nil;
Class parentClass = [ultimateParentViewT class];
while (parent && [parent isKindOfClass:parentClass]==NO) {
parent = parent.superview;
}
return static_cast<ultimateParentViewT*>(parent);
}
template <class parentViewControllerT, class ultimateParentViewT=UITableView>
parentViewControllerT* safeParentDelegate(UIView* ofView)
{
if (ofView == nil)
return nil;
UIView* parent = ofView.superview;
if (parent == nil)
return nil;
Class wantedParent = [ultimateParentViewT class];
while (parent && [parent isKindOfClass:wantedParent]==NO) {
parent = parent.superview;
}
if (parent == nil)
return nil;
auto parentView = static_cast<ultimateParentViewT*>(parent);
id parentDelegate = [parentView delegate];
return static_cast<parentViewControllerT*>(parentDelegate);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment