From f27186d9c68b18f685ed988701bb9cd6d233e903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=5B=CC=B2=CC=B2=CC=85=CC=85L=CC=B2=CC=85=CC=85e=CC=B2o?= =?UTF-8?q?=CC=B2=CC=85=5D?= Date: Thu, 28 Apr 2016 22:30:38 +0300 Subject: [PATCH] Add support for split view controllers Other visual tweaks Closes #63 Closes #60 --- LNPopupController/Info.plist | 2 +- .../Private/LNPopupCloseButton.m | 2 +- .../Private/LNPopupController.m | 6 +- .../UIViewController+LNPopupSupportPrivate.m | 33 ++++++- .../Base.lproj/Main.storyboard | 90 ++++++++++++++++--- .../DemoMusicPlayerController.swift | 2 +- .../FirstViewController.m | 67 ++++++++++---- 7 files changed, 170 insertions(+), 32 deletions(-) diff --git a/LNPopupController/Info.plist b/LNPopupController/Info.plist index 9dd65a2d..55867191 100644 --- a/LNPopupController/Info.plist +++ b/LNPopupController/Info.plist @@ -9,7 +9,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.4.1 + 1.4.2 CFBundleVersion 1 LSRequiresIPhoneOS diff --git a/LNPopupController/LNPopupController/Private/LNPopupCloseButton.m b/LNPopupController/LNPopupController/Private/LNPopupCloseButton.m index ee8f8c14..9796bead 100644 --- a/LNPopupController/LNPopupController/Private/LNPopupCloseButton.m +++ b/LNPopupController/LNPopupController/Private/LNPopupCloseButton.m @@ -112,7 +112,7 @@ - (void)layoutSubviews _effectView.frame = self.bounds; CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; - maskLayer.rasterizationScale = 2.0 * [UIScreen mainScreen].nativeScale; + maskLayer.rasterizationScale = [UIScreen mainScreen].nativeScale; maskLayer.shouldRasterize = YES; CGPathRef path = CGPathCreateWithRoundedRect(self.bounds, minSideSize / 2, minSideSize / 2, NULL); diff --git a/LNPopupController/LNPopupController/Private/LNPopupController.m b/LNPopupController/LNPopupController/Private/LNPopupController.m index 0b54a945..b2e56b90 100644 --- a/LNPopupController/LNPopupController/Private/LNPopupController.m +++ b/LNPopupController/LNPopupController/Private/LNPopupController.m @@ -298,14 +298,17 @@ - (void)_transitionToState:(LNPopupPresentationState)state animated:(BOOL)animat contentController.view.frame = _containerController.view.bounds; contentController.view.clipsToBounds = NO; contentController.view.autoresizingMask = UIViewAutoresizingNone; + if(CGColorGetAlpha(contentController.view.backgroundColor.CGColor) < 1.0) { //Support for iOS8, where this property was exposed as readonly. [self.popupContentView setValue:[UIBlurEffect effectWithStyle:_popupBar.barStyle == UIBarStyleDefault ? UIBlurEffectStyleExtraLight : UIBlurEffectStyleDark] forKey:@"effect"]; + self.popupContentView.popupCloseButton.layer.shadowOpacity = 0.2; } else { [self.popupContentView setValue:nil forKey:@"effect"]; + self.popupContentView.popupCloseButton.layer.shadowOpacity = 0.1; } [self.popupContentView.contentView addSubview:contentController.view]; @@ -555,7 +558,7 @@ - (void)_configurePopupBarFromBottomBar - (void)_movePopupBarAndContentToBottomBarSuperview { - NSAssert(_bottomBar.superview != nil, @"Bottom docking view must have a superview before presenting popup."); +// NSAssert(_bottomBar.superview != nil, @"Bottom docking view must have a superview before presenting popup."); [_popupBar removeFromSuperview]; [_bottomBar.superview insertSubview:_popupBar belowSubview:_bottomBar]; [_popupBar.superview bringSubviewToFront:_popupBar]; @@ -577,7 +580,6 @@ - (LNPopupContentView *)popupContentView _popupContentView.contentView.preservesSuperviewLayoutMargins = YES; _popupContentView.popupCloseButton = [[LNPopupCloseButton alloc] initWithFrame: CGRectMake(0, 0, 0, 0)]; - _popupContentView.popupCloseButton.clipsToBounds = YES; [_popupContentView.popupCloseButton addTarget:self action:@selector(_closePopupContent) forControlEvents:UIControlEventTouchUpInside]; [_popupContentView.contentView addSubview:self.popupContentView.popupCloseButton]; diff --git a/LNPopupController/LNPopupController/Private/UIViewController+LNPopupSupportPrivate.m b/LNPopupController/LNPopupController/Private/UIViewController+LNPopupSupportPrivate.m index bb9f8e1a..aaef83ba 100644 --- a/LNPopupController/LNPopupController/Private/UIViewController+LNPopupSupportPrivate.m +++ b/LNPopupController/LNPopupController/Private/UIViewController+LNPopupSupportPrivate.m @@ -433,6 +433,7 @@ + (void)load }); } +#ifndef LNPopupControllerEnforceStrictClean //Support for `hidesBottomBarWhenPushed`. - (void)_sTH:(BOOL)arg1 e:(unsigned int)arg2 d:(double)arg3; { @@ -469,7 +470,6 @@ - (void)_sTH:(BOOL)arg1 e:(unsigned int)arg2 d:(double)arg3; }]; } -#ifndef LNPopupControllerEnforceStrictClean - (UIEdgeInsets)eIFCVC:(UIViewController*)controller iAA:(BOOL*)absolute { UIEdgeInsets rv = [self _ln_common_eIFCVC:controller iAA:absolute]; @@ -494,3 +494,34 @@ - (nullable UIViewController *)_ln_childViewControllerForStatusBarStyle } @end + +@interface UISplitViewController (LNPopupSupportPrivate) @end +@implementation UISplitViewController (LNPopupSupportPrivate) + ++ (void)load +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Method m1 = class_getInstanceMethod([self class], @selector(viewDidLayoutSubviews)); + Method m2 = class_getInstanceMethod([self class], @selector(_ln_popup_viewDidLayoutSubviews_SplitViewNastyApple)); + method_exchangeImplementations(m1, m2); + }); +} + +- (void)_ln_popup_viewDidLayoutSubviews_SplitViewNastyApple +{ + [self _ln_popup_viewDidLayoutSubviews_SplitViewNastyApple]; + + if(self.bottomDockingViewForPopup_nocreate != nil) + { + //Apple forgot to call the super implementation of viewDidLayoutSubviews, but we need that to layout the popup bar correctly. + struct objc_super superInfo = { + self, + [UIViewController class] + }; + void (*super_call)(struct objc_super*, SEL) = (void (*)(struct objc_super*, SEL))objc_msgSendSuper; + super_call(&superInfo, @selector(viewDidLayoutSubviews)); + } +} + +@end \ No newline at end of file diff --git a/LNPopupControllerExample/LNPopupControllerExample/Base.lproj/Main.storyboard b/LNPopupControllerExample/LNPopupControllerExample/Base.lproj/Main.storyboard index b4a86d16..d72112fc 100644 --- a/LNPopupControllerExample/LNPopupControllerExample/Base.lproj/Main.storyboard +++ b/LNPopupControllerExample/LNPopupControllerExample/Base.lproj/Main.storyboard @@ -1,7 +1,7 @@ - + - + @@ -16,9 +16,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -37,7 +77,7 @@ - + @@ -57,7 +97,7 @@ - + @@ -81,7 +121,7 @@ - + @@ -112,7 +152,7 @@ - + @@ -136,6 +176,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -219,12 +285,13 @@ + - + @@ -262,7 +329,7 @@ - + @@ -280,12 +347,13 @@ - + + - + diff --git a/LNPopupControllerExample/LNPopupControllerExample/DemoMusicPlayerController.swift b/LNPopupControllerExample/LNPopupControllerExample/DemoMusicPlayerController.swift index b5fc655e..40801539 100644 --- a/LNPopupControllerExample/LNPopupControllerExample/DemoMusicPlayerController.swift +++ b/LNPopupControllerExample/LNPopupControllerExample/DemoMusicPlayerController.swift @@ -32,7 +32,7 @@ class DemoMusicPlayerController: UIViewController { } - timer = NSTimer.scheduledTimerWithTimeInterval(0.05, target: self, selector: "_timerTicked:", userInfo: nil, repeats: true) + timer = NSTimer.scheduledTimerWithTimeInterval(0.05, target: self, selector: #selector(DemoMusicPlayerController._timerTicked(_:)), userInfo: nil, repeats: true) } var songTitle: String = "" { diff --git a/LNPopupControllerExample/LNPopupControllerExample/FirstViewController.m b/LNPopupControllerExample/LNPopupControllerExample/FirstViewController.m index f51a3717..da8946ff 100644 --- a/LNPopupControllerExample/LNPopupControllerExample/FirstViewController.m +++ b/LNPopupControllerExample/LNPopupControllerExample/FirstViewController.m @@ -11,6 +11,19 @@ #import "LoremIpsum.h" #import "RandomColors.h" +@interface WhatsUpSplitViewController : UISplitViewController + +@end + +@implementation WhatsUpSplitViewController + +- (void)viewDidLayoutSubviews +{ + [super viewDidLayoutSubviews]; +} + +@end + @interface DemoGalleryController : UITableViewController @end @implementation DemoGalleryController @@ -77,19 +90,23 @@ - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation @implementation FirstViewController { __weak IBOutlet UIButton *_galleryButton; - + __weak IBOutlet UIButton *_nextButton; } -#warning Enable this code to demonstrate popup bar customization +// TODO: Uncomment this code to demonstrate popup bar customization + //+ (void)load //{ -// NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; -// paragraphStyle.alignment = NSTextAlignmentRight; -// -// [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UIViewController class]]] setTitleTextAttributes:@{NSParagraphStyleAttributeName: paragraphStyle, NSFontAttributeName: [UIFont fontWithName:@"Chalkduster" size:14], NSForegroundColorAttributeName: [UIColor yellowColor]}]; -// [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UIViewController class]]] setSubtitleTextAttributes:@{NSParagraphStyleAttributeName: paragraphStyle, NSFontAttributeName: [UIFont fontWithName:@"Chalkduster" size:12], NSForegroundColorAttributeName: [UIColor greenColor]}]; -// [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UIViewController class]]] setBarStyle:UIBarStyleBlack]; -// [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UIViewController class]]] setTintColor:[UIColor yellowColor]]; +// static dispatch_once_t onceToken; +// dispatch_once(&onceToken, ^{ +// NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; +// paragraphStyle.alignment = NSTextAlignmentRight; +// +// [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UIViewController class]]] setTitleTextAttributes:@{NSParagraphStyleAttributeName: paragraphStyle, NSFontAttributeName: [UIFont fontWithName:@"Chalkduster" size:14], NSForegroundColorAttributeName: [UIColor yellowColor]}]; +// [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UIViewController class]]] setSubtitleTextAttributes:@{NSParagraphStyleAttributeName: paragraphStyle, NSFontAttributeName: [UIFont fontWithName:@"Chalkduster" size:12], NSForegroundColorAttributeName: [UIColor greenColor]}]; +// [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UIViewController class]]] setBarStyle:UIBarStyleBlack]; +// [[LNPopupBar appearanceWhenContainedInInstancesOfClasses:@[[UIViewController class]]] setTintColor:[UIColor yellowColor]]; +// }); //} - (void)viewDidLoad @@ -98,7 +115,8 @@ - (void)viewDidLoad self.view.backgroundColor = LNRandomLightColor(); -#warning Enable this code to demonstrate disabling the popup close button. +// TODO: Uncomment this code to demonstrate disabling the popup close button. + // self.navigationController.popupContentView.popupCloseButton.hidden = YES; } @@ -108,7 +126,11 @@ - (void)viewWillAppear:(BOOL)animated //Ugly hack to fix tab bar tint color. self.tabBarController.view.tintColor = [UIColor redColor]; - _galleryButton.hidden = self.parentViewController != nil; + //Ugly hack to fix split view controller tint color. + self.splitViewController.view.tintColor = [UIColor redColor]; + + _galleryButton.hidden = self.parentViewController != nil && [self.parentViewController isKindOfClass:[UISplitViewController class]] == NO; + _nextButton.hidden = self.splitViewController != nil; } - (void)viewDidAppear:(BOOL)animated @@ -133,14 +155,29 @@ - (IBAction)_changeBarStyle:(id)sender - (IBAction)_presentBar:(id)sender { - UIViewController* targetVC = self.tabBarController; + //All this logic is just so I can use the same controllers over and over in all examples. :-) + + if(sender == nil && + self.navigationController == nil && + self.splitViewController != nil && + self != self.splitViewController.viewControllers.firstObject) + { + return; + } + + UIViewController* targetVC = self.navigationController == nil ? self.splitViewController : nil; + if(targetVC == nil) { - targetVC = self.navigationController; - + targetVC = self.tabBarController; if(targetVC == nil) { - targetVC = self; + targetVC = self.navigationController; + + if(targetVC == nil) + { + targetVC = self; + } } }