mirror of
https://github.com/LeoNatan/LNPopupController.git
synced 2026-07-30 16:11:51 +00:00
465 lines
15 KiB
Objective-C
465 lines
15 KiB
Objective-C
//
|
|
// FirstViewController.m
|
|
// LNPopupControllerExample
|
|
//
|
|
// Created by Leo Natan on 7/16/15.
|
|
// Copyright © 2015 Leo Natan. All rights reserved.
|
|
//
|
|
|
|
#if LNPOPUP
|
|
@import LNPopupController;
|
|
#endif
|
|
#import "FirstViewController.h"
|
|
#import "DemoPopupContentViewController.h"
|
|
#import "LoremIpsum.h"
|
|
#import "RandomColors.h"
|
|
#import "SettingsTableViewController.h"
|
|
#import "SplitViewController.h"
|
|
@import UIKit;
|
|
|
|
extern UIImage* LNSystemImage(NSString* named);
|
|
|
|
@interface TabBar : UITabBar @end
|
|
@implementation TabBar
|
|
|
|
- (void)setFrame:(CGRect)frame
|
|
{
|
|
// NSLog(@"🤦♂️ frame: %@ safe area: %@", @(frame), [self valueForKey:@"safeAreaInsets"]);
|
|
|
|
[super setFrame:frame];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface Toolbar : UIToolbar @end
|
|
@implementation Toolbar
|
|
|
|
- (void)setFrame:(CGRect)frame
|
|
{
|
|
// NSLog(@"🤦♂️ frame: %@ safe area: %@", @(frame), [self valueForKey:@"safeAreaInsets"]);
|
|
|
|
[super setFrame:frame];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface FirstView : UIView @end
|
|
|
|
@implementation FirstView
|
|
|
|
- (void)willMoveToWindow:(UIWindow *)newWindow
|
|
{
|
|
[super willMoveToWindow:newWindow];
|
|
}
|
|
|
|
- (void)didMoveToWindow
|
|
{
|
|
[super didMoveToWindow];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface FirstViewController () <UINavigationControllerDelegate
|
|
#if LNPOPUP
|
|
, UIContextMenuInteractionDelegate, LNPopupPresentationDelegate
|
|
#endif
|
|
>
|
|
|
|
@property (nonatomic, strong) NSString* colorSeedString;
|
|
@property (nonatomic) NSInteger colorSeedCount;
|
|
|
|
@end
|
|
|
|
@implementation FirstViewController
|
|
{
|
|
__weak IBOutlet UIButton *_galleryButton;
|
|
__weak IBOutlet UIButton *_nextButton;
|
|
|
|
__weak IBOutlet UIBarButtonItem *_barStyleButton;
|
|
BOOL _alreadyPresentedAutomatically;
|
|
}
|
|
|
|
- (UITabBarItem *)tabBarItem
|
|
{
|
|
if(self.tabBarController != nil)
|
|
{
|
|
UIViewController* target = self;
|
|
if(self.navigationController != nil)
|
|
{
|
|
target = self.navigationController;
|
|
}
|
|
|
|
super.tabBarItem.image = LNSystemImage([NSString stringWithFormat:@"%lu.square.fill", [self.tabBarController.viewControllers indexOfObject:target] + 1]);
|
|
}
|
|
|
|
return super.tabBarItem;
|
|
}
|
|
|
|
|
|
- (void)viewDidLoad
|
|
{
|
|
[super viewDidLoad];
|
|
|
|
if(self.colorSeedString == nil)
|
|
{
|
|
if(self.splitViewController != nil)
|
|
{
|
|
self.colorSeedString = [NSString stringWithFormat:@"%@", @(arc4random())];
|
|
}
|
|
else if(self.tabBarController != nil)
|
|
{
|
|
NSUInteger tabIdx = [self.tabBarController.viewControllers indexOfObject:self.navigationController ?: self];
|
|
self.colorSeedString = [NSString stringWithFormat:@"tab_%@", @(tabIdx)];
|
|
}
|
|
else if(self.navigationController != nil)
|
|
{
|
|
self.colorSeedString = [NSString stringWithFormat:@"tab_109"];
|
|
}
|
|
else
|
|
{
|
|
self.colorSeedString = @"nil";
|
|
}
|
|
self.colorSeedCount = 0;
|
|
}
|
|
|
|
NSString* seed = [NSString stringWithFormat:@"%@%@", self.colorSeedString, self.colorSeedCount == 0 ? @"" : [NSString stringWithFormat:@"%@", @(self.colorSeedCount)]];
|
|
if (@available(iOS 13.0, *))
|
|
{
|
|
self.view.backgroundColor = LNSeedAdaptiveColor(seed);
|
|
} else {
|
|
self.view.backgroundColor = LNSeedLightColor(seed);
|
|
}
|
|
|
|
self.navigationController.delegate = self;
|
|
}
|
|
|
|
- (void)viewWillAppear:(BOOL)animated
|
|
{
|
|
[super viewWillAppear:animated];
|
|
|
|
//Ugly hack to fix tab bar tint color.
|
|
self.tabBarController.view.tintColor = self.view.tintColor;
|
|
//Ugly hack to fix split view controller tint color.
|
|
self.splitViewController.view.tintColor = self.view.tintColor;
|
|
//Ugly hack to fix navigation view controller tint color.
|
|
self.navigationController.view.tintColor = self.view.tintColor;
|
|
|
|
_galleryButton.titleLabel.adjustsFontForContentSizeCategory = YES;
|
|
_nextButton.titleLabel.adjustsFontForContentSizeCategory = YES;
|
|
|
|
_galleryButton.hidden = [self.parentViewController isKindOfClass:[UINavigationController class]];
|
|
_nextButton.hidden = self.navigationController == nil || self.splitViewController != nil;
|
|
|
|
if(self.tabBarController == nil || self.navigationController.topViewController == self.navigationController.viewControllers.firstObject)
|
|
{
|
|
[self _presentBar:nil animated:NO];
|
|
}
|
|
}
|
|
|
|
- (void)viewDidAppear:(BOOL)animated
|
|
{
|
|
[super viewDidAppear:animated];
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
|
|
}
|
|
|
|
- (IBAction)_changeBarStyle:(id)sender
|
|
{
|
|
if (@available(iOS 13.0, *))
|
|
{
|
|
UIUserInterfaceStyle currentStyle = self.navigationController.traitCollection.userInterfaceStyle;
|
|
|
|
self.navigationController.overrideUserInterfaceStyle = currentStyle == UIUserInterfaceStyleLight ? UIUserInterfaceStyleDark : UIUserInterfaceStyleLight;
|
|
}
|
|
else
|
|
{
|
|
self.navigationController.toolbar.barStyle = 1 - self.navigationController.toolbar.barStyle;
|
|
}
|
|
|
|
self.navigationController.toolbar.tintColor = LNRandomSystemColor();
|
|
|
|
[self.navigationController.toolbar.items enumerateObjectsUsingBlock:^(UIBarButtonItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
obj.tintColor = self.navigationController.toolbar.tintColor;
|
|
}];
|
|
self.navigationController.navigationBar.barStyle = self.navigationController.toolbar.barStyle;
|
|
self.navigationController.navigationBar.tintColor = self.navigationController.toolbar.tintColor;
|
|
|
|
[self.navigationController setNeedsPopupBarAppearanceUpdate];
|
|
}
|
|
|
|
- (UIViewController*)_targetVCForPopup
|
|
{
|
|
if([self.splitViewController isKindOfClass:SplitViewControllerPrimaryPopup.class] && self.navigationController != [self.ln_splitViewController viewControllerForColumn:LNSplitViewControllerColumnPrimary])
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
NSMutableArray* vcs = @[self].mutableCopy;
|
|
if(self.navigationController)
|
|
{
|
|
[vcs addObject:self.navigationController];
|
|
}
|
|
if([self.splitViewController isKindOfClass:SplitViewControllerSecondaryPopup.class] && [vcs containsObject:[self.ln_splitViewController viewControllerForColumn:LNSplitViewControllerColumnPrimary]])
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
if([self.splitViewController isKindOfClass:SplitViewControllerSecondaryPopup.class] && [vcs containsObject:[self.ln_splitViewController viewControllerForColumn:LNSplitViewControllerColumnSupplementary]])
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
if([self.splitViewController isKindOfClass:SplitViewControllerGlobalPopup.class])
|
|
{
|
|
return self.splitViewController;
|
|
}
|
|
|
|
UIViewController* targetVC = self.tabBarController;
|
|
|
|
if(targetVC == nil)
|
|
{
|
|
targetVC = self.navigationController;
|
|
|
|
if(targetVC == nil)
|
|
{
|
|
targetVC = self;
|
|
}
|
|
}
|
|
|
|
return targetVC;
|
|
}
|
|
|
|
- (IBAction)_presentBar:(id)sender
|
|
{
|
|
[self _presentBar:sender animated:YES];
|
|
}
|
|
|
|
- (void)_presentBar:(id)sender animated:(BOOL)animated;
|
|
{
|
|
#if LNPOPUP
|
|
if(_alreadyPresentedAutomatically == YES && sender == nil)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(sender == nil)
|
|
{
|
|
_alreadyPresentedAutomatically = YES;
|
|
}
|
|
|
|
UIViewController* targetVC = [self _targetVCForPopup];
|
|
|
|
if(targetVC == nil)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(targetVC.popupContentViewController != nil)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(targetVC == self.navigationController && self.navigationController.viewControllers.count > 1 && self.splitViewController == nil && sender == nil)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// UIViewController* demoVC = [self.storyboard instantiateViewControllerWithIdentifier:@"SettingsTableViewController"];
|
|
UIViewController* demoVC = [DemoPopupContentViewController new];
|
|
|
|
uint32_t titleLowerLimit = 2;
|
|
uint32_t titleUpperLimit = 5;
|
|
|
|
uint32_t subtitleLowerLimit = 4;
|
|
uint32_t subtitleUpperLimit = 16;
|
|
|
|
demoVC.popupItem.title = [[LoremIpsum wordsWithNumber:arc4random_uniform(titleUpperLimit - titleLowerLimit) + titleLowerLimit] capitalizedString];
|
|
demoVC.popupItem.subtitle = [[LoremIpsum wordsWithNumber:arc4random_uniform(subtitleUpperLimit - subtitleLowerLimit) + subtitleLowerLimit] valueForKey:@"li_stringByCapitalizingFirstLetter"];
|
|
|
|
if([NSUserDefaults.standardUserDefaults boolForKey:@"NSForceRightToLeftWritingDirection"])
|
|
{
|
|
demoVC.popupItem.title = [demoVC.popupItem.title stringByApplyingTransform:NSStringTransformLatinToHebrew reverse:NO];
|
|
demoVC.popupItem.subtitle = [demoVC.popupItem.subtitle stringByApplyingTransform:NSStringTransformLatinToHebrew reverse:NO];
|
|
}
|
|
|
|
demoVC.popupItem.image = [UIImage imageNamed:@"genre7"];
|
|
demoVC.popupItem.progress = (float) arc4random() / UINT32_MAX;
|
|
|
|
LNPopupCloseButtonStyle closeButtonStyle = [[[NSUserDefaults standardUserDefaults] objectForKey:PopupSettingsCloseButtonStyle] unsignedIntegerValue];
|
|
|
|
UILabel* topLabel = [UILabel new];
|
|
topLabel.text = NSLocalizedString(@"Top", @"");
|
|
if (@available(iOS 13.0, *)) {
|
|
topLabel.textColor = [UIColor systemBackgroundColor];
|
|
} else {
|
|
topLabel.textColor = [UIColor lightTextColor];
|
|
}
|
|
topLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
|
|
topLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
|
[demoVC.view addSubview:topLabel];
|
|
|
|
CGFloat offset =
|
|
#if ! TARGET_OS_MACCATALYST
|
|
closeButtonStyle == LNPopupCloseButtonStyleDefault ||
|
|
#endif
|
|
closeButtonStyle == LNPopupCloseButtonStyleChevron || closeButtonStyle == LNPopupCloseButtonStyleGrabber ? 40 : 0;
|
|
|
|
[NSLayoutConstraint activateConstraints:@[
|
|
[topLabel.topAnchor constraintEqualToAnchor:demoVC.view.safeAreaLayoutGuide.topAnchor],
|
|
[topLabel.centerXAnchor constraintEqualToAnchor:demoVC.view.safeAreaLayoutGuide.centerXAnchor constant:offset]
|
|
]];
|
|
|
|
UILabel* bottomLabel = [UILabel new];
|
|
bottomLabel.text = NSLocalizedString(@"Bottom", @"");
|
|
if (@available(iOS 13.0, *)) {
|
|
bottomLabel.textColor = [UIColor systemBackgroundColor];
|
|
} else {
|
|
bottomLabel.textColor = [UIColor lightTextColor];
|
|
}
|
|
bottomLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
|
|
bottomLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
|
[demoVC.view addSubview:bottomLabel];
|
|
[NSLayoutConstraint activateConstraints:@[
|
|
[bottomLabel.bottomAnchor constraintEqualToAnchor:demoVC.view.safeAreaLayoutGuide.bottomAnchor],
|
|
[bottomLabel.centerXAnchor constraintEqualToAnchor:demoVC.view.safeAreaLayoutGuide.centerXAnchor]
|
|
]];
|
|
|
|
demoVC.popupItem.accessibilityLabel = NSLocalizedString(@"Custom popup bar accessibility label", @"");
|
|
demoVC.popupItem.accessibilityHint = NSLocalizedString(@"Custom popup bar accessibility hint", @"");
|
|
|
|
targetVC.popupContentView.popupCloseButton.accessibilityLabel = NSLocalizedString(@"Custom popup button accessibility label", @"");
|
|
targetVC.popupContentView.popupCloseButton.accessibilityHint = NSLocalizedString(@"Custom popup button accessibility hint", @"");
|
|
|
|
targetVC.popupBar.progressViewStyle = [[[NSUserDefaults standardUserDefaults] objectForKey:PopupSettingsProgressViewStyle] unsignedIntegerValue];
|
|
targetVC.popupBar.barStyle = [[[NSUserDefaults standardUserDefaults] objectForKey:PopupSettingsBarStyle] unsignedIntegerValue];
|
|
targetVC.popupInteractionStyle = [[[NSUserDefaults standardUserDefaults] objectForKey:PopupSettingsInteractionStyle] unsignedIntegerValue];
|
|
targetVC.popupContentView.popupCloseButtonStyle = closeButtonStyle;
|
|
|
|
targetVC.shouldExtendPopupBarUnderSafeArea = [NSUserDefaults.standardUserDefaults boolForKey:PopupSettingsExtendBar];
|
|
|
|
// if (@available(iOS 13.0, *))
|
|
// {
|
|
// UIContextMenuInteraction* i = [[UIContextMenuInteraction alloc] initWithDelegate:self];
|
|
// [targetVC.popupBar addInteraction:i];
|
|
// }
|
|
|
|
targetVC.popupPresentationDelegate = self;
|
|
[targetVC presentPopupBarWithContentViewController:demoVC animated:animated completion:nil];
|
|
#endif
|
|
}
|
|
|
|
- (IBAction)_dismissBar:(id)sender
|
|
{
|
|
#if LNPOPUP
|
|
__kindof UIViewController* targetVC = [self _targetVCForPopup];
|
|
[targetVC dismissPopupBarAnimated:YES completion:nil];
|
|
#endif
|
|
}
|
|
|
|
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
|
|
{
|
|
segue.destinationViewController.hidesBottomBarWhenPushed = [NSUserDefaults.standardUserDefaults boolForKey:PopupSettingsHidesBottomBarWhenPushed];
|
|
if([segue.destinationViewController isKindOfClass:FirstViewController.class])
|
|
{
|
|
[(FirstViewController*)segue.destinationViewController setColorSeedString:self.colorSeedString];
|
|
[(FirstViewController*)segue.destinationViewController setColorSeedCount:self.colorSeedCount + 1];
|
|
}
|
|
}
|
|
|
|
#pragma mark UINavigationControllerDelegate
|
|
|
|
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
|
|
{
|
|
//Mask Apple's push bug. This uses private API, so don't copy it as is in your app!
|
|
|
|
if(@available(iOS 14.0, *))
|
|
{
|
|
UIViewController* disappearing = [navigationController valueForKey:@"disappearingViewController"];
|
|
UIViewController* target = viewController;
|
|
BOOL isPushing = [[navigationController valueForKey:@"isPushing"] boolValue];
|
|
|
|
self.tabBarController.view.backgroundColor = (isPushing ? target : disappearing).view.backgroundColor;
|
|
}
|
|
}
|
|
|
|
#pragma mark UIContextMenuInteractionDelegate
|
|
|
|
#if LNPOPUP
|
|
- (nullable UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location API_AVAILABLE(ios(13.0))
|
|
{
|
|
return [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:nil actionProvider:nil];
|
|
}
|
|
|
|
- (void)contextMenuInteraction:(UIContextMenuInteraction *)interaction willEndForConfiguration:(UIContextMenuConfiguration *)configuration animator:(nullable id<UIContextMenuInteractionAnimating>)animator API_AVAILABLE(ios(13.0))
|
|
{
|
|
[animator addAnimations:^{
|
|
UIActivityViewController* avc = [[UIActivityViewController alloc] initWithActivityItems:@[[NSURL URLWithString:@"https://github.com/LeoNatan/LNPopupController"]] applicationActivities:nil];
|
|
avc.modalPresentationStyle = UIModalPresentationFormSheet;
|
|
avc.popoverPresentationController.sourceView = [self _targetVCForPopup].popupBar;
|
|
[self presentViewController:avc animated:YES completion:nil];
|
|
}];
|
|
|
|
[animator addCompletion:^{
|
|
|
|
}];
|
|
}
|
|
#endif
|
|
|
|
#pragma mark LNPopupPresentationDelegate
|
|
|
|
- (void)popupPresentationControllerWillPresentPopupBar:(UIViewController*)popupPresentationController animated:(BOOL)animated
|
|
{
|
|
|
|
}
|
|
|
|
- (void)popupPresentationControllerDidPresentPopupBar:(UIViewController*)popupPresentationController animated:(BOOL)animated
|
|
{
|
|
|
|
}
|
|
|
|
- (void)popupPresentationControllerWillDismissPopupBar:(UIViewController*)popupPresentationController animated:(BOOL)animated
|
|
{
|
|
|
|
}
|
|
|
|
- (void)popupPresentationControllerDidDismissPopupBar:(UIViewController*)popupPresentationController animated:(BOOL)animated
|
|
{
|
|
|
|
}
|
|
|
|
- (void)popupPresentationController:(UIViewController *)popupPresentationController willOpenPopupWithContentController:(UIViewController *)popupContentController animated:(BOOL)animated
|
|
{
|
|
|
|
}
|
|
|
|
- (void)popupPresentationController:(UIViewController *)popupPresentationController didOpenPopupWithContentController:(UIViewController *)popupContentController animated:(BOOL)animated
|
|
{
|
|
|
|
}
|
|
|
|
- (void)popupPresentationController:(UIViewController *)popupPresentationController willClosePopupWithContentController:(UIViewController *)popupContentController animated:(BOOL)animated
|
|
{
|
|
|
|
}
|
|
|
|
- (void)popupPresentationController:(UIViewController *)popupPresentationController didClosePopupWithContentController:(UIViewController *)popupContentController animated:(BOOL)animated
|
|
{
|
|
|
|
}
|
|
|
|
|
|
@end
|
|
|
|
@interface PassthroughNavigationController : UINavigationController @end
|
|
@implementation PassthroughNavigationController
|
|
|
|
- (UITabBarItem *)tabBarItem
|
|
{
|
|
return self.viewControllers.firstObject.tabBarItem;
|
|
}
|
|
|
|
@end
|