Question

I am using ECSlidingViewController for "hamburger" menu. I am using SDK 7.0 but I changed deployment target to iOS 6.1 and now I am trying my app with older iOS then 7. The problem is with setEdgesForExtendedLayout. There is older ECSlidingViewController for older system versions. So my question is how can I change to use old version for iOS 6.1 and older and newer version for iOS 7.0 and newer. I include files from both ECSlidingViewController projects (not by cocoapods but if it is need then it's not problem to change it). I guess I need check for OS version and then change imports but I am not sure if it is enough and what's best name convention for both project. I guess they should be in different folders (like ECSlidingViewController and ECSlidingViewControllerOld) but class should be same name, is it right?

Edit: Example of code with edgesForExtendedLayout:

- (CGRect)underLeftViewCalculatedFrameForTopViewPosition:(ECSlidingViewControllerTopViewPosition)position {
    CGRect frameFromDelegate = [self frameFromDelegateForViewController:self.underLeftViewController
                                                        topViewPosition:position];
    if (!CGRectIsInfinite(frameFromDelegate)) return frameFromDelegate;

    CGRect containerViewFrame = self.view.bounds;

    if (!(self.underLeftViewController.edgesForExtendedLayout & UIRectEdgeTop)) {
        CGFloat topLayoutGuideLength    = [self.topLayoutGuide length];
        containerViewFrame.origin.y     = topLayoutGuideLength;
        containerViewFrame.size.height -= topLayoutGuideLength;
    }

    if (!(self.underLeftViewController.edgesForExtendedLayout & UIRectEdgeBottom)) {
        CGFloat bottomLayoutGuideLength = [self.bottomLayoutGuide length];
        containerViewFrame.size.height -= bottomLayoutGuideLength;
    }

    if (!(self.underLeftViewController.edgesForExtendedLayout & UIRectEdgeRight)) {
        containerViewFrame.size.width = self.anchorRightRevealAmount;
    }

    return containerViewFrame;
}
Was it helpful?

Solution

I am not a fan of including duplicate versions of libraries, as this creates a big problem with naming, and a lot of work to refactor all old classes to have some *-OLD suffix. Since you have access to the source, you can modify the newer version like so:

if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)
{
    [vc setEdgesForExtendedLayout:UIRectEdgeNone];

    //Any other iOS7-specific code.
}

OTHER TIPS

First, the easiest way to do it will be have the most recent version of component that support the lowest deployment target.

But if you really want to have different version for each iOS, I don't know better solution, than just rename all classes from, for example, older version (because there was only two classes) and manage creation of this controller programmatically, because there's no way to set different class for different iOS version in xib's or storyboard's. You need to wrap each and every call of this component with iOS version check ( How to check iOS version? ).

Imports and variables you can leave for each version of component without check.

The trick you mentioned failed in this case, because it works good for different architecture, because binaries for different architectures will be included in final app and that's named fat binary, but there's the same architecture for iOS6 and iOS7 ( only one new in iOS7 - arm64). So you can't wrap only includes with preprocessor macros and get fat binary with different code for each iOS version.

I hope you've understood something from my explanation.

It seems that the only thing preventing you from using the new version with iOS 6 is the lack of topLayoutGuide and bottomLayoutGuide, which if available would just return lengths of zero anyway.

Why not "backport" those methods in your controller?

- (id<UILayoutSupport>)topLayoutGuide
{
    CustomLayoutGuide * guide = [CustomLayoutGuide new];
    guide.length = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0") ? super.topLayoutGuide.length : 0.0;
    return guide;
}

And the helper class

@interface CustomLayoutGuide : NSObject <UILayoutSupport>

@property(nonatomic) CGFloat length;

@end

@implementation CustomLayoutGuide

@end

IMHO the easiest thing to do (and probably the best though) is to take the current ECSlidingViewController and integrate part of the old when edgesForExtendedLayout is not available (e.g. if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) { /*...*/} ). This should be pretty easy and fast to do since the old ECSlidingViewController just consists of two files and these files are also present in the new ECSlidingViewController. You could make your life even easier when doing this by using a diff tool to be sure of what you should add.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top