From 07e667a95dbb6ac8c1ab1bfac80e5ffb83e7d9ba Mon Sep 17 00:00:00 2001 From: David Sinclair Date: Tue, 15 Dec 2015 12:37:18 -0800 Subject: [PATCH] iOS: tweaked #825 (dark mode) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminated the old WYPopoverController from the code, since it isn’t needed and isn’t compatible with theming. All popovers now use the modern UIPopoverPresentationController mechanism. --- clients/ios/Classes/AddSiteViewController.m | 12 +- .../Classes/FeedDetailMenuViewController.m | 5 +- .../ios/Classes/FeedDetailViewController.h | 5 +- .../ios/Classes/FeedDetailViewController.m | 49 +- clients/ios/Classes/FeedsMenuViewController.m | 5 +- .../ios/Classes/NBContainerViewController.h | 9 +- .../ios/Classes/NBContainerViewController.m | 100 +- clients/ios/Classes/NewsBlurAppDelegate.h | 10 +- clients/ios/Classes/NewsBlurAppDelegate.m | 110 +- clients/ios/Classes/NewsBlurViewController.h | 5 - clients/ios/Classes/NewsBlurViewController.m | 89 +- .../ios/Classes/StoryDetailViewController.m | 2 +- clients/ios/Classes/StoryPageControl.h | 8 +- clients/ios/Classes/StoryPageControl.m | 40 +- clients/ios/Classes/TrainerViewController.m | 4 +- .../ios/NewsBlur.xcodeproj/project.pbxproj | 21 - .../WYPopoverController/WYPopoverController.h | 278 -- .../WYPopoverController/WYPopoverController.m | 2948 ----------------- .../WYStoryboardPopoverSegue.h | 40 - .../WYStoryboardPopoverSegue.m | 97 - 20 files changed, 120 insertions(+), 3717 deletions(-) delete mode 100755 clients/ios/Other Sources/WYPopoverController/WYPopoverController.h delete mode 100755 clients/ios/Other Sources/WYPopoverController/WYPopoverController.m delete mode 100755 clients/ios/Other Sources/WYPopoverController/WYStoryboardPopoverSegue.h delete mode 100755 clients/ios/Other Sources/WYPopoverController/WYStoryboardPopoverSegue.m diff --git a/clients/ios/Classes/AddSiteViewController.m b/clients/ios/Classes/AddSiteViewController.m index 78ebc6861..2dff6ffab 100644 --- a/clients/ios/Classes/AddSiteViewController.m +++ b/clients/ios/Classes/AddSiteViewController.m @@ -133,10 +133,9 @@ - (IBAction)doCancelButton { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [appDelegate.masterContainerViewController hidePopover]; + [self.appDelegate hidePopover]; } else { - [appDelegate.feedsViewController.popoverController dismissPopoverAnimated:YES]; - appDelegate.feedsViewController.popoverController = nil; + [self.appDelegate hidePopoverAnimated:YES]; } } @@ -310,12 +309,11 @@ [self.errorLabel setHidden:NO]; } else { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [appDelegate.masterContainerViewController hidePopover]; + [self.appDelegate hidePopover]; } else { - [appDelegate.feedsViewController.popoverController dismissPopoverAnimated:YES]; - appDelegate.feedsViewController.popoverController = nil; + [self.appDelegate hidePopoverAnimated:YES]; } - [appDelegate reloadFeedsView:NO]; + [self.appDelegate reloadFeedsView:NO]; } } diff --git a/clients/ios/Classes/FeedDetailMenuViewController.m b/clients/ios/Classes/FeedDetailMenuViewController.m index a9ecdf045..a55543542 100644 --- a/clients/ios/Classes/FeedDetailMenuViewController.m +++ b/clients/ios/Classes/FeedDetailMenuViewController.m @@ -189,10 +189,9 @@ } if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [appDelegate.masterContainerViewController hidePopover]; + [self.appDelegate hidePopover]; } else { - [appDelegate.feedDetailViewController.popoverController dismissPopoverAnimated:YES]; - appDelegate.feedDetailViewController.popoverController = nil; + [self.appDelegate hidePopoverAnimated:YES]; } [tableView deselectRowAtIndexPath:indexPath animated:YES]; diff --git a/clients/ios/Classes/FeedDetailViewController.h b/clients/ios/Classes/FeedDetailViewController.h index f91d5a019..594f22e63 100644 --- a/clients/ios/Classes/FeedDetailViewController.h +++ b/clients/ios/Classes/FeedDetailViewController.h @@ -11,7 +11,6 @@ #import "ASIHTTPRequest.h" #import "BaseViewController.h" #import "Utilities.h" -#import "WYPopoverController.h" #import "NBNotifier.h" #import "MCSwipeTableViewCell.h" @@ -22,7 +21,7 @@ @interface FeedDetailViewController : BaseViewController { NewsBlurAppDelegate *appDelegate; @@ -37,7 +36,6 @@ UITableView * storyTitlesTable; UIBarButtonItem * feedMarkReadButton; - WYPopoverController *popoverController; Class popoverClass; NBNotifier *notifier; } @@ -50,7 +48,6 @@ @property (nonatomic) IBOutlet UIBarButtonItem * spacer2BarButton; @property (nonatomic) IBOutlet UIBarButtonItem * separatorBarButton; @property (nonatomic) IBOutlet UIBarButtonItem * titleImageBarButton; -@property (nonatomic, retain) WYPopoverController *popoverController; @property (nonatomic, retain) NBNotifier *notifier; @property (nonatomic, retain) StoriesCollection *storiesCollection; @property (nonatomic) UISearchBar *searchBar; diff --git a/clients/ios/Classes/FeedDetailViewController.m b/clients/ios/Classes/FeedDetailViewController.m index 9734142a0..771b8370f 100644 --- a/clients/ios/Classes/FeedDetailViewController.m +++ b/clients/ios/Classes/FeedDetailViewController.m @@ -23,7 +23,6 @@ #import "NSObject+SBJSON.h" #import "StringHelper.h" #import "Utilities.h" -#import "WYPopoverController.h" #import "UIBarButtonItem+Image.h" #import "FeedDetailMenuViewController.h" #import "MarkReadMenuViewController.h" @@ -51,7 +50,6 @@ @implementation FeedDetailViewController -@synthesize popoverController; @synthesize storyTitlesTable, feedMarkReadButton; @synthesize settingsBarButton; @synthesize separatorBarButton; @@ -87,7 +85,6 @@ name:UIContentSizeCategoryDidChangeNotification object:nil]; - popoverClass = [WYPopoverController class]; self.storyTitlesTable.backgroundColor = UIColorFromRGB(0xf4f4f4); self.storyTitlesTable.separatorColor = UIColorFromRGB(0xE9E8E4); @@ -431,8 +428,7 @@ [super viewDidDisappear:animated]; [self.searchBar resignFirstResponder]; - [self.popoverController dismissPopoverAnimated:YES]; - self.popoverController = nil; + [self.appDelegate hidePopoverAnimated:YES]; UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if (self.isMovingToParentViewController) { @@ -1818,8 +1814,7 @@ didEndSwipingSwipingWithState:(MCSwipeTableViewCellState)state } - (IBAction)doOpenMarkReadMenu:(id)sender { - [self.popoverController dismissPopoverAnimated:YES]; - self.popoverController = nil; + [self.appDelegate hidePopoverAnimated:YES]; void (^pop)(void) = ^{ if (!self.isPhoneOrCompact) { @@ -1865,30 +1860,13 @@ didEndSwipingSwipingWithState:(MCSwipeTableViewCellState)state return; } - if (!self.isPhoneOrCompact) { - [appDelegate.masterContainerViewController showFeedDetailMenuPopover:self.settingsBarButton]; - } else { - if (self.popoverController == nil) { - self.popoverController = [[WYPopoverController alloc] - initWithContentViewController:(UIViewController *)appDelegate.feedDetailMenuViewController]; - [appDelegate.feedDetailMenuViewController buildMenuOptions]; - self.popoverController.delegate = self; - } else { - [self.popoverController dismissPopoverAnimated:YES]; - self.popoverController = nil; - } - - NSInteger menuCount = [appDelegate.feedDetailMenuViewController.menuOptions count] + 2; - [self.popoverController setPopoverContentSize:CGSizeMake(260, 38 * menuCount)]; - [self.popoverController presentPopoverFromBarButtonItem:self.settingsBarButton - permittedArrowDirections:UIPopoverArrowDirectionUp - animated:YES]; - } - + [self.appDelegate.feedDetailMenuViewController buildMenuOptions]; + [self.appDelegate.feedDetailMenuViewController view]; + NSInteger menuCount = [self.appDelegate.feedDetailMenuViewController.menuOptions count] + 2; + + [self.appDelegate showPopoverWithViewController:self.appDelegate.feedDetailMenuViewController contentSize:CGSizeMake(260, 38 * menuCount) barButtonItem:self.settingsBarButton]; } - - - (void)confirmDeleteSite { UIAlertView *deleteConfirm = [[UIAlertView alloc] initWithTitle:@"Positive?" @@ -2247,17 +2225,4 @@ didEndSwipingSwipingWithState:(MCSwipeTableViewCellState)state [appDelegate informError:error]; } -#pragma mark - -#pragma mark WYPopoverControllerDelegate implementation - -- (void)popoverControllerDidDismissPopover:(WYPopoverController *)thePopoverController { - //Safe to release the popover here - self.popoverController = nil; -} - -- (BOOL)popoverControllerShouldDismissPopover:(WYPopoverController *)thePopoverController { - //The popover is automatically dismissed if you click outside it, unless you return NO here - return YES; -} - @end diff --git a/clients/ios/Classes/FeedsMenuViewController.m b/clients/ios/Classes/FeedsMenuViewController.m index 75049bd61..e5d2e8e8a 100644 --- a/clients/ios/Classes/FeedsMenuViewController.m +++ b/clients/ios/Classes/FeedsMenuViewController.m @@ -126,10 +126,9 @@ } if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [appDelegate.masterContainerViewController hidePopover]; + [self.appDelegate hidePopover]; } else { - [appDelegate.feedsViewController.popoverController dismissPopoverAnimated:YES]; - appDelegate.feedsViewController.popoverController = nil; + [self.appDelegate hidePopoverAnimated:YES]; } [tableView deselectRowAtIndexPath:indexPath animated:YES]; diff --git a/clients/ios/Classes/NBContainerViewController.h b/clients/ios/Classes/NBContainerViewController.h index e6fba0045..f68e33abe 100644 --- a/clients/ios/Classes/NBContainerViewController.h +++ b/clients/ios/Classes/NBContainerViewController.h @@ -25,6 +25,7 @@ @property (nonatomic) CALayer *leftBorder; @property (nonatomic) CALayer *rightBorder; @property (atomic, strong) IBOutlet NewsBlurAppDelegate *appDelegate; +@property (nonatomic, readonly) UINavigationController *masterNavigationController; - (void)syncNextPreviousButtons; @@ -49,12 +50,6 @@ - (void)dragStoryToolbar:(int)yCoordinate; - (void)showUserProfilePopover:(id)sender; -- (void)showFeedMenuPopover:(id)sender; -- (void)showFeedDetailMenuPopover:(id)sender; -- (void)showFontSettingsPopover:(id)sender; - (void)showTrainingPopover:(id)sender; -- (void)showUserTagsPopover:(id)sender; -- (void)showSitePopover:(id)sender; -- (BOOL)hidePopoverAnimated:(BOOL)animated; -- (void)hidePopover; + @end diff --git a/clients/ios/Classes/NBContainerViewController.m b/clients/ios/Classes/NBContainerViewController.m index 644bdcd38..1b09d776f 100644 --- a/clients/ios/Classes/NBContainerViewController.m +++ b/clients/ios/Classes/NBContainerViewController.m @@ -303,115 +303,39 @@ # pragma mark Modals and Popovers -- (void)showPopoverWithViewController:(UIViewController *)viewController contentSize:(CGSize)contentSize barButtonItem:(UIBarButtonItem *)barButtonItem { - [self showPopoverWithViewController:viewController contentSize:contentSize barButtonItem:barButtonItem sourceView:nil sourceRect:CGRectZero]; -} - -- (void)showPopoverWithViewController:(UIViewController *)viewController contentSize:(CGSize)contentSize sourceView:(UIView *)sourceView sourceRect:(CGRect)sourceRect { - [self showPopoverWithViewController:viewController contentSize:contentSize barButtonItem:nil sourceView:sourceView sourceRect:sourceRect]; -} - -- (void)showPopoverWithViewController:(UIViewController *)viewController contentSize:(CGSize)contentSize barButtonItem:(UIBarButtonItem *)barButtonItem sourceView:(UIView *)sourceView sourceRect:(CGRect)sourceRect { - if (viewController == self.masterNavigationController.presentedViewController) - return; // nothing to do, already showing this controller - - [self hidePopoverAnimated:YES]; - - viewController.modalPresentationStyle = UIModalPresentationPopover; - viewController.preferredContentSize = contentSize; - - UIPopoverPresentationController *popoverPresentationController = viewController.popoverPresentationController; - popoverPresentationController.delegate = self; - popoverPresentationController.backgroundColor = UIColorFromRGB(NEWSBLUR_WHITE_COLOR); - popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny; - - if (barButtonItem) { - popoverPresentationController.barButtonItem = barButtonItem; - } else { - popoverPresentationController.sourceView = sourceView; - popoverPresentationController.sourceRect = sourceRect; - } - - [self.masterNavigationController presentViewController:viewController animated:YES completion:nil]; -} - - (void)showUserProfilePopover:(id)sender { if ([sender class] == [InteractionCell class] || [sender class] == [ActivityCell class]) { InteractionCell *cell = (InteractionCell *)sender; - [self showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) sourceView:cell sourceRect:cell.bounds]; + [self.appDelegate showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) sourceView:cell sourceRect:cell.bounds]; } else if ([sender class] == [FeedTableCell class]) { FeedTableCell *cell = (FeedTableCell *)sender; - [self showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) sourceView:cell sourceRect:cell.bounds]; + [self.appDelegate showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) sourceView:cell sourceRect:cell.bounds]; } else if ([sender class] == [UIBarButtonItem class]) { - [self showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) barButtonItem:sender]; + [self.appDelegate showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) barButtonItem:sender]; } else { CGRect frame = [sender CGRectValue]; - [self showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) sourceView:self.storyPageControl.view sourceRect:frame]; + [self.appDelegate showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) sourceView:self.storyPageControl.view sourceRect:frame]; } } -- (void)showSitePopover:(id)sender { - [self showPopoverWithViewController:self.appDelegate.addSiteViewController contentSize:CGSizeMake(320, 355) barButtonItem:sender]; -} - -- (void)showFeedMenuPopover:(id)sender { - [self.appDelegate.feedsMenuViewController view]; - NSInteger menuCount = [self.appDelegate.feedsMenuViewController.menuOptions count]; - - [self showPopoverWithViewController:self.appDelegate.feedsMenuViewController contentSize:CGSizeMake(200, 38 * menuCount) barButtonItem:sender]; -} - -- (void)showFeedDetailMenuPopover:(id)sender { - [appDelegate.feedDetailMenuViewController buildMenuOptions]; - [appDelegate.feedDetailMenuViewController view]; - NSInteger menuCount = [self.appDelegate.feedDetailMenuViewController.menuOptions count] + 2; - - [self showPopoverWithViewController:self.appDelegate.feedDetailMenuViewController contentSize:CGSizeMake(260, 38 * menuCount) barButtonItem:sender]; -} - -- (void)showFontSettingsPopover:(id)sender { - [self showPopoverWithViewController:self.appDelegate.fontSettingsNavigationController contentSize:CGSizeMake(240.0, 306.0) barButtonItem:sender]; -} - - (void)showTrainingPopover:(id)sender { if ([sender class] == [UIBarButtonItem class]) { - [self showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) barButtonItem:sender]; + [self.appDelegate showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) barButtonItem:sender]; } else if ([sender class] == [FeedTableCell class]) { FeedTableCell *cell = (FeedTableCell *)sender; - [self showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) sourceView:cell sourceRect:cell.bounds]; + [self.appDelegate showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) sourceView:cell sourceRect:cell.bounds]; } else if ([sender class] == [FeedDetailTableCell class]) { FeedDetailTableCell *cell = (FeedDetailTableCell *)sender; - [self showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) sourceView:cell sourceRect:cell.bounds]; + [self.appDelegate showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) sourceView:cell sourceRect:cell.bounds]; } else { CGRect frame = [sender CGRectValue]; - [self showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) sourceView:self.storyPageControl.view sourceRect:frame]; + [self.appDelegate showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) sourceView:self.storyPageControl.view sourceRect:frame]; } } -- (void)showUserTagsPopover:(id)sender { - [appDelegate.userTagsViewController view]; // Force viewDidLoad - CGRect frame = [sender CGRectValue]; - [self showPopoverWithViewController:self.appDelegate.userTagsViewController contentSize:CGSizeMake(220, 382) sourceView:self.storyPageControl.view sourceRect:frame]; -} - -- (BOOL)hidePopoverAnimated:(BOOL)animated { - UIViewController *presentedViewController = self.masterNavigationController.presentedViewController; - if (!presentedViewController) - return NO; - - [presentedViewController dismissViewControllerAnimated:animated completion:nil]; - return YES; -} - -- (void)hidePopover { - [self hidePopoverAnimated:YES]; - [appDelegate.modalNavigationController dismissViewControllerAnimated:YES completion:nil]; -} - - - (void)syncNextPreviousButtons { [self.storyPageControl setNextPreviousButtons]; } @@ -581,7 +505,7 @@ [self transitionToFeedDetail:YES]; } - (void)transitionToFeedDetail:(BOOL)resetLayout { - [self hidePopover]; + [self.appDelegate hidePopover]; if (self.feedDetailIsVisible) resetLayout = NO; self.feedDetailIsVisible = YES; @@ -856,7 +780,7 @@ return; } - [self hidePopover]; + [self.appDelegate hidePopover]; if (self.isSharingStory) { [self transitionFromShareView]; @@ -936,7 +860,7 @@ return; } - [self hidePopover]; + [self.appDelegate hidePopover]; CGRect vb = [self.view bounds]; self.isSharingStory = YES; self.storyPageControl.traverseView.hidden = YES; @@ -970,7 +894,7 @@ return; } - [self hidePopover]; + [self.appDelegate hidePopover]; CGRect vb = [self.view bounds]; self.isSharingStory = NO; self.storyPageControl.traverseView.hidden = NO; diff --git a/clients/ios/Classes/NewsBlurAppDelegate.h b/clients/ios/Classes/NewsBlurAppDelegate.h index e130aa8eb..44f613698 100644 --- a/clients/ios/Classes/NewsBlurAppDelegate.h +++ b/clients/ios/Classes/NewsBlurAppDelegate.h @@ -11,7 +11,6 @@ #import "BaseViewController.h" #import "FMDatabaseQueue.h" #import "EventWindow.h" -#import "WYPopoverController.h" #define FEED_DETAIL_VIEW_TAG 1000001 #define STORY_DETAIL_VIEW_TAG 1000002 @@ -50,7 +49,7 @@ @class TMCache; @interface NewsBlurAppDelegate : BaseViewController - { EventWindow *window; UINavigationController *ftuxNavigationController; @@ -86,7 +85,6 @@ SFSafariViewControllerDelegate> { UINavigationController *originalStoryViewNavController; UserProfileViewController *userProfileViewController; IASKAppSettingsViewController *preferencesViewController; - WYPopoverController *popoverController; NSString * activeUsername; NSString * activeUserProfileId; @@ -175,7 +173,6 @@ SFSafariViewControllerDelegate> { @property (nonatomic) IBOutlet FontSettingsViewController *fontSettingsViewController; @property (nonatomic) IBOutlet UserProfileViewController *userProfileViewController; @property (nonatomic) IBOutlet IASKAppSettingsViewController *preferencesViewController; -@property (nonatomic, retain) WYPopoverController *popoverController; @property (nonatomic, strong) UINavigationController *fontSettingsNavigationController; @property (nonatomic, strong) MarkReadMenuViewController *markReadMenuViewController; @property (nonatomic) IBOutlet FirstTimeUserViewController *firstTimeUserViewController; @@ -349,6 +346,11 @@ SFSafariViewControllerDelegate> { - (void)showMarkReadMenuWithFeedIds:(NSArray *)feedIds collectionTitle:(NSString *)collectionTitle sourceView:(UIView *)sourceView sourceRect:(CGRect)sourceRect completionHandler:(void (^)(BOOL marked))completionHandler; - (void)showMarkOlderNewerReadMenuWithStoriesCollection:(StoriesCollection *)olderNewerCollection story:(NSDictionary *)olderNewerStory sourceView:(UIView *)sourceView sourceRect:(CGRect)sourceRect completionHandler:(void (^)(BOOL marked))completionHandler; +- (void)showPopoverWithViewController:(UIViewController *)viewController contentSize:(CGSize)contentSize barButtonItem:(UIBarButtonItem *)barButtonItem; +- (void)showPopoverWithViewController:(UIViewController *)viewController contentSize:(CGSize)contentSize sourceView:(UIView *)sourceView sourceRect:(CGRect)sourceRect; +- (BOOL)hidePopoverAnimated:(BOOL)animated; +- (void)hidePopover; + + (int)computeStoryScore:(NSDictionary *)intelligence; - (NSString *)extractFolderName:(NSString *)folderName; - (NSString *)extractParentFolderName:(NSString *)folderName; diff --git a/clients/ios/Classes/NewsBlurAppDelegate.m b/clients/ios/Classes/NewsBlurAppDelegate.m index 497877434..a66d549af 100644 --- a/clients/ios/Classes/NewsBlurAppDelegate.m +++ b/clients/ios/Classes/NewsBlurAppDelegate.m @@ -103,7 +103,6 @@ @synthesize originalStoryViewNavController; @synthesize userProfileViewController; @synthesize preferencesViewController; -@synthesize popoverController; @synthesize firstTimeUserViewController; @synthesize firstTimeUserAddSitesViewController; @@ -445,7 +444,7 @@ - (void)hideUserProfileModal { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [self.masterContainerViewController hidePopover]; + [self hidePopover]; } else { [self.navigationController dismissViewControllerAnimated:YES completion:nil]; } @@ -610,7 +609,7 @@ }]; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - BOOL fromPopover = [self.masterContainerViewController hidePopoverAnimated:NO]; + BOOL fromPopover = [self hidePopoverAnimated:NO]; [self.masterContainerViewController presentViewController:activityViewController animated:!fromPopover completion:nil]; activityViewController.modalPresentationStyle = UIModalPresentationPopover; // iOS 8+ @@ -808,27 +807,9 @@ self.userTagsViewController = [[UserTagsViewController alloc] init]; } - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [self.masterContainerViewController showUserTagsPopover:sender]; - } else { - if (self.popoverController == nil) { - self.popoverController = [[WYPopoverController alloc] - initWithContentViewController:self.userTagsViewController]; - - self.popoverController.delegate = self; - } else { - [self.popoverController dismissPopoverAnimated:YES]; - self.popoverController = nil; - } - - [self.userTagsViewController view]; // Force viewDidLoad - [self.popoverController setPopoverContentSize:CGSizeMake(220, 38 * MIN(6.5, [[self.dictSavedStoryTags allKeys] count] + [self.activeStory[@"user_tags"] count] + 1))]; - CGRect frame = [sender CGRectValue]; - [self.popoverController presentPopoverFromRect:frame - inView:self.storyPageControl.currentPage.view - permittedArrowDirections:WYPopoverArrowDirectionAny - animated:YES]; - } + [self.userTagsViewController view]; // Force viewDidLoad + CGRect frame = [sender CGRectValue]; + [self showPopoverWithViewController:self.userTagsViewController contentSize:CGSizeMake(220, 382) sourceView:self.storyPageControl.view sourceRect:frame]; } #pragma mark - UIPopoverPresentationControllerDelegate @@ -837,19 +818,6 @@ return UIModalPresentationNone; } -#pragma mark - -#pragma mark WYPopoverControllerDelegate implementation - -- (void)popoverControllerDidDismissPopover:(WYPopoverController *)thePopoverController { - //Safe to release the popover here - self.popoverController = nil; -} - -- (BOOL)popoverControllerShouldDismissPopover:(WYPopoverController *)thePopoverController { - //The popover is automatically dismissed if you click outside it, unless you return NO here - return YES; -} - #pragma mark - - (void)reloadFeedsView:(BOOL)showLoader { @@ -926,9 +894,8 @@ [self loadFeedDetailView]; } else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { [self.navigationController popToRootViewControllerAnimated:NO]; - if (self.feedsViewController.popoverController) { - [self.feedsViewController.popoverController dismissPopoverAnimated:YES]; - } + [self hidePopoverAnimated:YES]; + if (self.navigationController.presentedViewController) { [self.navigationController dismissViewControllerAnimated:YES completion:^{ [self loadFeedDetailView]; @@ -944,9 +911,7 @@ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { [self.navigationController popToRootViewControllerAnimated:NO]; [self.navigationController dismissViewControllerAnimated:YES completion:nil]; - if (self.feedsViewController.popoverController) { - [self.feedsViewController.popoverController dismissPopoverAnimated:NO]; - } + [self hidePopoverAnimated:NO]; } self.inFindingStoryMode = YES; @@ -1232,9 +1197,7 @@ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { [self.navigationController popToRootViewControllerAnimated:NO]; [self.navigationController dismissViewControllerAnimated:YES completion:nil]; - if (self.feedsViewController.popoverController) { - [self.feedsViewController.popoverController dismissPopoverAnimated:NO]; - } + [self hidePopoverAnimated:NO]; } self.inFindingStoryMode = YES; @@ -2098,6 +2061,61 @@ [self.navigationController presentViewController:self.markReadMenuViewController animated:YES completion:nil]; } +- (void)showPopoverWithViewController:(UIViewController *)viewController contentSize:(CGSize)contentSize barButtonItem:(UIBarButtonItem *)barButtonItem { + [self showPopoverWithViewController:viewController contentSize:contentSize barButtonItem:barButtonItem sourceView:nil sourceRect:CGRectZero]; +} + +- (void)showPopoverWithViewController:(UIViewController *)viewController contentSize:(CGSize)contentSize sourceView:(UIView *)sourceView sourceRect:(CGRect)sourceRect { + [self showPopoverWithViewController:viewController contentSize:contentSize barButtonItem:nil sourceView:sourceView sourceRect:sourceRect]; +} + +- (void)showPopoverWithViewController:(UIViewController *)viewController contentSize:(CGSize)contentSize barButtonItem:(UIBarButtonItem *)barButtonItem sourceView:(UIView *)sourceView sourceRect:(CGRect)sourceRect { + if (viewController == self.navigationControllerForPopover.presentedViewController) { + return; // nothing to do, already showing this controller + } + + [self hidePopoverAnimated:YES]; + + viewController.modalPresentationStyle = UIModalPresentationPopover; + viewController.preferredContentSize = contentSize; + + UIPopoverPresentationController *popoverPresentationController = viewController.popoverPresentationController; + popoverPresentationController.delegate = self; + popoverPresentationController.backgroundColor = UIColorFromRGB(NEWSBLUR_WHITE_COLOR); + popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny; + + if (barButtonItem) { + popoverPresentationController.barButtonItem = barButtonItem; + } else { + popoverPresentationController.sourceView = sourceView; + popoverPresentationController.sourceRect = sourceRect; + } + + [self.navigationControllerForPopover presentViewController:viewController animated:YES completion:nil]; +} + +- (BOOL)hidePopoverAnimated:(BOOL)animated { + UIViewController *presentedViewController = self.navigationControllerForPopover.presentedViewController; + if (!presentedViewController || presentedViewController.presentationController.presentationStyle != UIModalPresentationPopover) + return NO; + + [presentedViewController dismissViewControllerAnimated:animated completion:nil]; + return YES; +} + +- (void)hidePopover { + [self hidePopoverAnimated:YES]; + [self.modalNavigationController dismissViewControllerAnimated:YES completion:nil]; +} + +- (UINavigationController *)navigationControllerForPopover { + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { + return self.masterContainerViewController.masterNavigationController; + } else { + return self.navigationController; + } +} + #pragma mark - #pragma mark Story functions diff --git a/clients/ios/Classes/NewsBlurViewController.h b/clients/ios/Classes/NewsBlurViewController.h index caf122b18..0fda39fd0 100644 --- a/clients/ios/Classes/NewsBlurViewController.h +++ b/clients/ios/Classes/NewsBlurViewController.h @@ -12,7 +12,6 @@ #import "ASIHTTPRequest.h" #import "PullToRefreshView.h" #import "BaseViewController.h" -#import "WYPopoverController.h" #import "NBNotifier.h" #import "IASKAppSettingsViewController.h" #import "MCSwipeTableViewCell.h" @@ -23,7 +22,6 @@ { UIBarButtonItem * settingsBarButton; UIBarButtonItem * activitiesButton; UISegmentedControl * intelligenceControl; - WYPopoverController *popoverController; - Class popoverClass; NBNotifier *notifier; } @@ -80,7 +76,6 @@ UIGestureRecognizerDelegate> { @property (nonatomic) NSDate *lastUpdate; @property (nonatomic) NSCache *imageCache; @property (nonatomic) IBOutlet UISegmentedControl * intelligenceControl; -@property (nonatomic, retain) WYPopoverController *popoverController; @property (nonatomic) NSIndexPath *currentRowAtIndexPath; @property (nonatomic) NSInteger currentSection; @property (strong, nonatomic) IBOutlet UIView *noFocusMessage; diff --git a/clients/ios/Classes/NewsBlurViewController.m b/clients/ios/Classes/NewsBlurViewController.m index 98ccb0071..985c62a47 100644 --- a/clients/ios/Classes/NewsBlurViewController.m +++ b/clients/ios/Classes/NewsBlurViewController.m @@ -70,7 +70,6 @@ static UIFont *userLabelFont; @synthesize pull; @synthesize lastUpdate; @synthesize imageCache; -@synthesize popoverController; @synthesize currentRowAtIndexPath; @synthesize currentSection; @synthesize noFocusMessage; @@ -103,8 +102,6 @@ static UIFont *userLabelFont; - (void)viewDidLoad { [super viewDidLoad]; - popoverClass = [WYPopoverController class]; - pull = [[PullToRefreshView alloc] initWithScrollView:self.feedTitlesTable]; self.pull.tintColor = UIColorFromLightDarkRGB(0x0, 0xffffff); self.pull.backgroundColor = UIColorFromRGB(0xE3E6E0); @@ -329,8 +326,7 @@ static UIFont *userLabelFont; } - (void)viewWillDisappear:(BOOL)animated { - [self.popoverController dismissPopoverAnimated:YES]; - self.popoverController = nil; + [self.appDelegate hidePopoverAnimated:YES]; [super viewWillDisappear:animated]; } @@ -834,68 +830,23 @@ static UIFont *userLabelFont; } - (IBAction)tapAddSite:(id)sender { - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [appDelegate.masterContainerViewController showSitePopover:self.addBarButton]; - } else { - if (self.popoverController == nil) { - self.popoverController = [[WYPopoverController alloc] - initWithContentViewController:appDelegate.addSiteViewController]; - - self.popoverController.delegate = self; - } else { - [self.popoverController dismissPopoverAnimated:YES]; - self.popoverController = nil; - } - - [self.popoverController setPopoverContentSize:CGSizeMake(self.view.frame.size.width - 36, - MIN(self.view.frame.size.height - 28, 355))]; - [self.popoverController presentPopoverFromBarButtonItem:self.addBarButton - permittedArrowDirections:UIPopoverArrowDirectionDown - animated:YES]; - } - - [appDelegate.addSiteViewController reload]; + [self.appDelegate showPopoverWithViewController:self.appDelegate.addSiteViewController contentSize:CGSizeMake(320, 355) barButtonItem:self.addBarButton]; + [self.appDelegate.addSiteViewController reload]; } - (IBAction)showSettingsPopover:(id)sender { - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [appDelegate.masterContainerViewController showFeedMenuPopover:self.settingsBarButton]; - } else { - if (self.popoverController == nil) { - self.popoverController = [[WYPopoverController alloc] - initWithContentViewController:appDelegate.feedsMenuViewController]; - - self.popoverController.delegate = self; - } else { - [self.popoverController dismissPopoverAnimated:YES]; - self.popoverController = nil; - } - - [appDelegate.feedsMenuViewController view]; // Force viewDidLoad - [self.popoverController setPopoverContentSize:CGSizeMake(200, 38 * [appDelegate.feedsMenuViewController.menuOptions count])]; - [self.popoverController presentPopoverFromBarButtonItem:self.settingsBarButton - permittedArrowDirections:UIPopoverArrowDirectionDown - animated:YES]; - } + [self.appDelegate.feedsMenuViewController view]; + NSInteger menuCount = [self.appDelegate.feedsMenuViewController.menuOptions count]; + + [self.appDelegate showPopoverWithViewController:self.appDelegate.feedsMenuViewController contentSize:CGSizeMake(200, 38 * menuCount) barButtonItem:self.settingsBarButton]; } -- (IBAction)showInteractionsPopover:(id)sender { - if (self.popoverController == nil) { - self.popoverController = [[WYPopoverController alloc] - initWithContentViewController:appDelegate.dashboardViewController]; - - self.popoverController.delegate = self; - } else { - [self.popoverController dismissPopoverAnimated:YES]; - self.popoverController = nil; - } +- (IBAction)showInteractionsPopover:(id)sender { + CGSize size = CGSizeMake(self.view.frame.size.width - 36, + self.view.frame.size.height - 60); + + [self.appDelegate showPopoverWithViewController:self.appDelegate.dashboardViewController contentSize:size barButtonItem:self.activitiesButton]; - [self.popoverController setPopoverContentSize:CGSizeMake(self.view.frame.size.width - 36, - self.view.frame.size.height - 60)]; - [self.popoverController presentPopoverFromBarButtonItem:self.activitiesButton - permittedArrowDirections:UIPopoverArrowDirectionUp - animated:YES]; - [appDelegate.dashboardViewController refreshInteractions]; [appDelegate.dashboardViewController refreshActivity]; } @@ -1002,8 +953,7 @@ static UIFont *userLabelFont; [self.presentedViewController dismissViewControllerAnimated:YES completion:nil]; } - [self.popoverController dismissPopoverAnimated:YES]; - self.popoverController = nil; + [self.appDelegate hidePopoverAnimated:YES]; self.navigationController.navigationBar.tintColor = UIColorFromRGB(0x8F918B); self.navigationController.navigationBar.barTintColor = UIColorFromRGB(0xE3E6E0); @@ -1955,19 +1905,6 @@ heightForHeaderInSection:(NSInteger)section { return self.lastUpdate; } -#pragma mark - -#pragma mark WYPopoverControllerDelegate implementation - -- (void)popoverControllerDidDismissPopover:(WYPopoverController *)thePopoverController { - //Safe to release the popover here - self.popoverController = nil; -} - -- (BOOL)popoverControllerShouldDismissPopover:(WYPopoverController *)thePopoverController { - //The popover is automatically dismissed if you click outside it, unless you return NO here - return YES; -} - - (void)resetToolbar { self.navigationItem.leftBarButtonItem = nil; self.navigationItem.titleView = nil; diff --git a/clients/ios/Classes/StoryDetailViewController.m b/clients/ios/Classes/StoryDetailViewController.m index 572f99eb4..2b6a9e9cd 100644 --- a/clients/ios/Classes/StoryDetailViewController.m +++ b/clients/ios/Classes/StoryDetailViewController.m @@ -1506,7 +1506,7 @@ shouldStartLoadWithRequest:(NSURLRequest *)request - (void)showOriginalStory:(UIGestureRecognizer *)gesture { NSURL *url = [NSURL URLWithString:[appDelegate.activeStory objectForKey:@"story_permalink"]]; - [appDelegate.masterContainerViewController hidePopover]; + [appDelegate hidePopover]; if (!gesture || [gesture isKindOfClass:[UITapGestureRecognizer class]]) { [appDelegate showOriginalStory:url]; diff --git a/clients/ios/Classes/StoryPageControl.h b/clients/ios/Classes/StoryPageControl.h index c6aaf5b3b..94fd4b511 100644 --- a/clients/ios/Classes/StoryPageControl.h +++ b/clients/ios/Classes/StoryPageControl.h @@ -9,7 +9,6 @@ #import #import "BaseViewController.h" #import "NewsBlurAppDelegate.h" -#import "WYPopoverController.h" #import "THCircularProgressView.h" #import "NBNotifier.h" @@ -17,7 +16,7 @@ @class ASIHTTPRequest; @interface StoryPageControl : BaseViewController - { + { NewsBlurAppDelegate *appDelegate; @@ -31,9 +30,6 @@ UIView *progressView; UIView *progressViewContainer; - WYPopoverController *popoverController; - Class popoverClass; - BOOL isDraggingScrollview; BOOL isAnimatedIntoPlace; BOOL inRotation; @@ -82,8 +78,6 @@ @property (nonatomic, strong) NBNotifier *notifier; @property (nonatomic) NSInteger scrollingToPage; -@property (nonatomic, strong) WYPopoverController *popoverController; - - (void)resizeScrollView; - (void)applyNewIndex:(NSInteger)newIndex pageController:(StoryDetailViewController *)pageController; - (void)layoutForInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation; diff --git a/clients/ios/Classes/StoryPageControl.m b/clients/ios/Classes/StoryPageControl.m index cc36dfd58..1f5dd5d3a 100644 --- a/clients/ios/Classes/StoryPageControl.m +++ b/clients/ios/Classes/StoryPageControl.m @@ -45,7 +45,6 @@ @synthesize buttonBack; @synthesize bottomSize; @synthesize bottomSizeHeightConstraint; -@synthesize popoverController; @synthesize loadingIndicator; @synthesize inTouchMove; @synthesize isDraggingScrollview; @@ -102,9 +101,7 @@ [self.scrollView sizeToFit]; // NSLog(@"Scroll view frame post 2: %@", NSStringFromCGRect(self.scrollView.frame)); - popoverClass = [WYPopoverController class]; - - // adding HUD for progress bar + // adding HUD for progress bar CGFloat radius = 8; circularProgressView = [[THCircularProgressView alloc] initWithCenter:CGPointMake(self.buttonNext.frame.origin.x + 2*radius, @@ -1078,7 +1075,7 @@ } - (IBAction)showOriginalSubview:(id)sender { - [appDelegate.masterContainerViewController hidePopover]; + [appDelegate hidePopover]; NSURL *url = [NSURL URLWithString:[appDelegate.activeStory objectForKey:@"story_permalink"]]; @@ -1156,26 +1153,6 @@ // popPC.sourceRect = [sender frame]; [self presentViewController:self.appDelegate.fontSettingsNavigationController animated:YES completion:nil]; - return; - - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [appDelegate.masterContainerViewController showFontSettingsPopover:self.fontSettingsButton]; - } else { - if (self.popoverController == nil) { - self.popoverController = [[WYPopoverController alloc] - initWithContentViewController:appDelegate.fontSettingsNavigationController]; - - self.popoverController.delegate = self; - } else { - [self.popoverController dismissPopoverAnimated:YES]; - self.popoverController = nil; - } - - [self.popoverController setPopoverContentSize:CGSizeMake(240.0, 302.0)]; - [self.popoverController presentPopoverFromBarButtonItem:self.fontSettingsButton - permittedArrowDirections:UIPopoverArrowDirectionAny - animated:YES]; - } } - (void)setFontStyle:(NSString *)fontStyle { @@ -1292,19 +1269,6 @@ } } -#pragma mark - -#pragma mark WYPopoverControllerDelegate implementation - -- (void)popoverControllerDidDismissPopover:(WYPopoverController *)thePopoverController { - //Safe to release the popover here - self.popoverController = nil; -} - -- (BOOL)popoverControllerShouldDismissPopover:(WYPopoverController *)thePopoverController { - //The popover is automatically dismissed if you click outside it, unless you return NO here - return YES; -} - #pragma mark - UIPopoverPresentationControllerDelegate - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller { diff --git a/clients/ios/Classes/TrainerViewController.m b/clients/ios/Classes/TrainerViewController.m index fe377e667..77cee28a0 100644 --- a/clients/ios/Classes/TrainerViewController.m +++ b/clients/ios/Classes/TrainerViewController.m @@ -100,7 +100,7 @@ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^() { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [appDelegate.masterContainerViewController hidePopover]; + [appDelegate hidePopover]; } else { [appDelegate.navigationController dismissViewControllerAnimated:YES completion:nil]; } @@ -540,7 +540,7 @@ #pragma mark Actions - (IBAction)doCloseDialog:(id)sender { - [appDelegate.masterContainerViewController hidePopover]; + [appDelegate hidePopover]; [appDelegate.trainerViewController dismissViewControllerAnimated:YES completion:nil]; } diff --git a/clients/ios/NewsBlur.xcodeproj/project.pbxproj b/clients/ios/NewsBlur.xcodeproj/project.pbxproj index 596dd31d3..108e2e9ec 100755 --- a/clients/ios/NewsBlur.xcodeproj/project.pbxproj +++ b/clients/ios/NewsBlur.xcodeproj/project.pbxproj @@ -307,8 +307,6 @@ FF6281FA1A09614C00271FDB /* all@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = FF6281F91A09614C00271FDB /* all@3x.png */; }; FF6281FC1A0962FA00271FDB /* unread_green@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = FF6281FB1A0962FA00271FDB /* unread_green@3x.png */; }; FF6281FE1A09641100271FDB /* unread_yellow@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = FF6281FD1A09641100271FDB /* unread_yellow@3x.png */; }; - FF62820A1A098EA800271FDB /* WYPopoverController.m in Sources */ = {isa = PBXBuildFile; fileRef = FF6282071A098EA800271FDB /* WYPopoverController.m */; }; - FF62820B1A098EA800271FDB /* WYStoryboardPopoverSegue.m in Sources */ = {isa = PBXBuildFile; fileRef = FF6282091A098EA800271FDB /* WYStoryboardPopoverSegue.m */; }; FF62820E1A1160DD00271FDB /* add_tag.png in Resources */ = {isa = PBXBuildFile; fileRef = FF62820C1A1160DD00271FDB /* add_tag.png */; }; FF62820F1A1160DD00271FDB /* add_tag@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FF62820D1A1160DD00271FDB /* add_tag@2x.png */; }; FF6282151A11613900271FDB /* UserTagsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FF6282141A11613900271FDB /* UserTagsViewController.m */; }; @@ -923,10 +921,6 @@ FF6281F91A09614C00271FDB /* all@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "all@3x.png"; sourceTree = ""; }; FF6281FB1A0962FA00271FDB /* unread_green@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "unread_green@3x.png"; sourceTree = ""; }; FF6281FD1A09641100271FDB /* unread_yellow@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "unread_yellow@3x.png"; sourceTree = ""; }; - FF6282061A098EA800271FDB /* WYPopoverController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WYPopoverController.h; sourceTree = ""; }; - FF6282071A098EA800271FDB /* WYPopoverController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WYPopoverController.m; sourceTree = ""; }; - FF6282081A098EA800271FDB /* WYStoryboardPopoverSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WYStoryboardPopoverSegue.h; sourceTree = ""; }; - FF6282091A098EA800271FDB /* WYStoryboardPopoverSegue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WYStoryboardPopoverSegue.m; sourceTree = ""; }; FF62820C1A1160DD00271FDB /* add_tag.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = add_tag.png; sourceTree = ""; }; FF62820D1A1160DD00271FDB /* add_tag@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add_tag@2x.png"; sourceTree = ""; }; FF6282131A11613900271FDB /* UserTagsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserTagsViewController.h; sourceTree = ""; }; @@ -1301,7 +1295,6 @@ FF2EB77E1AA65504002549A7 /* InAppSettingsKit */, FF753CC2175858FC00344EC9 /* fmdb */, FF22FE5316E53ADC0046165A /* Underscore */, - FF6282051A098EA800271FDB /* WYPopoverController */, FF1F13CC18A9C2BE00FDA816 /* TMCache */, 43A4C3E615B0099B008787B5 /* NewsBlur_Prefix.pch */, 43A4C3B915B00966008787B5 /* ABTableViewCell.h */, @@ -2065,18 +2058,6 @@ name = Activities; sourceTree = ""; }; - FF6282051A098EA800271FDB /* WYPopoverController */ = { - isa = PBXGroup; - children = ( - FF6282061A098EA800271FDB /* WYPopoverController.h */, - FF6282071A098EA800271FDB /* WYPopoverController.m */, - FF6282081A098EA800271FDB /* WYStoryboardPopoverSegue.h */, - FF6282091A098EA800271FDB /* WYStoryboardPopoverSegue.m */, - ); - name = WYPopoverController; - path = "Other Sources/WYPopoverController"; - sourceTree = ""; - }; FF753CC2175858FC00344EC9 /* fmdb */ = { isa = PBXGroup; children = ( @@ -2668,7 +2649,6 @@ 7843F50511EEB1A000675F64 /* FeedDetailTableCell.m in Sources */, 784B50ED127E3F68008F90EA /* LoginViewController.m in Sources */, 78095E34128EF30C00230C8E /* ASIAuthenticationDialog.m in Sources */, - FF62820B1A098EA800271FDB /* WYStoryboardPopoverSegue.m in Sources */, 78095E35128EF30D00230C8E /* ASIDownloadCache.m in Sources */, FF2EB7B41AA65504002549A7 /* IASKSettingsReader.m in Sources */, 78095E36128EF30D00230C8E /* ASIFormDataRequest.m in Sources */, @@ -2688,7 +2668,6 @@ FF5EA47F143B691000B7563D /* AddSiteViewController.m in Sources */, FF1F13D818AAC97900FDA816 /* UIImage+Resize.m in Sources */, FFD887F01445F1E800385399 /* AddSiteAutocompleteCell.m in Sources */, - FF62820A1A098EA800271FDB /* WYPopoverController.m in Sources */, FF8D1ECD1BAA311000725D8A /* SBJson4StreamParser.m in Sources */, FFE5322F144C8AC300ACFDE0 /* Utilities.m in Sources */, FFD1D7311459B63500E46F89 /* BaseViewController.m in Sources */, diff --git a/clients/ios/Other Sources/WYPopoverController/WYPopoverController.h b/clients/ios/Other Sources/WYPopoverController/WYPopoverController.h deleted file mode 100755 index a88be99ed..000000000 --- a/clients/ios/Other Sources/WYPopoverController/WYPopoverController.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - Version 0.3.6 - - WYPopoverController is available under the MIT license. - - Copyright © 2013 Nicolas CHENG - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#import -#import -#import - -@protocol WYPopoverControllerDelegate; -@class WYPopoverTheme; - -#ifndef WY_POPOVER_DEFAULT_ANIMATION_DURATION -#define WY_POPOVER_DEFAULT_ANIMATION_DURATION .25f -#endif - -#ifndef WY_POPOVER_MIN_SIZE -#define WY_POPOVER_MIN_SIZE CGSizeMake(240, 160) -#endif - -typedef NS_OPTIONS(NSUInteger, WYPopoverArrowDirection) { - WYPopoverArrowDirectionUp = 1UL << 0, - WYPopoverArrowDirectionDown = 1UL << 1, - WYPopoverArrowDirectionLeft = 1UL << 2, - WYPopoverArrowDirectionRight = 1UL << 3, - WYPopoverArrowDirectionNone = 1UL << 4, - WYPopoverArrowDirectionAny = WYPopoverArrowDirectionUp | WYPopoverArrowDirectionDown | WYPopoverArrowDirectionLeft | WYPopoverArrowDirectionRight, - WYPopoverArrowDirectionUnknown = NSUIntegerMax -}; - -typedef NS_OPTIONS(NSUInteger, WYPopoverAnimationOptions) { - WYPopoverAnimationOptionFade = 1UL << 0, // default - WYPopoverAnimationOptionScale = 1UL << 1, - WYPopoverAnimationOptionFadeWithScale = WYPopoverAnimationOptionFade | WYPopoverAnimationOptionScale -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface WYPopoverBackgroundView : UIView - -// UI_APPEARANCE_SELECTOR doesn't support BOOLs on iOS 7, -// so these two need to be NSUInteger instead -@property (nonatomic, assign) NSUInteger usesRoundedArrow UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) NSUInteger dimsBackgroundViewsTintColor UI_APPEARANCE_SELECTOR; - -@property (nonatomic, strong) UIColor *tintColor UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIColor *fillTopColor UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIColor *fillBottomColor UI_APPEARANCE_SELECTOR; - -@property (nonatomic, strong) UIColor *glossShadowColor UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) CGSize glossShadowOffset UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) NSUInteger glossShadowBlurRadius UI_APPEARANCE_SELECTOR; - -@property (nonatomic, assign) NSUInteger borderWidth UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) NSUInteger arrowBase UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) NSUInteger arrowHeight UI_APPEARANCE_SELECTOR; - -@property (nonatomic, strong) UIColor *outerShadowColor UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIColor *outerStrokeColor UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) NSUInteger outerShadowBlurRadius UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) CGSize outerShadowOffset UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) NSUInteger outerCornerRadius UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) NSUInteger minOuterCornerRadius UI_APPEARANCE_SELECTOR; - -@property (nonatomic, strong) UIColor *innerShadowColor UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIColor *innerStrokeColor UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) NSUInteger innerShadowBlurRadius UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) CGSize innerShadowOffset UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) NSUInteger innerCornerRadius UI_APPEARANCE_SELECTOR; - -@property (nonatomic, assign) UIEdgeInsets viewContentInsets UI_APPEARANCE_SELECTOR; - -@property (nonatomic, strong) UIColor *overlayColor UI_APPEARANCE_SELECTOR; - -@property(nonatomic) CGFloat preferredAlpha UI_APPEARANCE_SELECTOR; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface WYPopoverController : NSObject - -@property (nonatomic, weak) id delegate; - -@property (nonatomic, assign) BOOL dismissOnTap; -@property (nonatomic, copy) NSArray *passthroughViews; -@property (nonatomic, assign) BOOL dismissOnPassthroughViewTap; -@property (nonatomic, assign) BOOL wantsDefaultContentAppearance; -@property (nonatomic, assign) UIEdgeInsets popoverLayoutMargins; -@property (nonatomic, readonly, getter=isPopoverVisible) BOOL popoverVisible; -@property (nonatomic, strong, readonly) UIViewController *contentViewController; -@property (nonatomic, assign) CGSize popoverContentSize; -@property (nonatomic, assign) float animationDuration; -@property (nonatomic, assign) BOOL implicitAnimationsDisabled; - -@property (nonatomic, strong) WYPopoverTheme *theme; - -@property (nonatomic, copy) void (^dismissCompletionBlock)(WYPopoverController *dimissedController); - -+ (void)setDefaultTheme:(WYPopoverTheme *)theme; -+ (WYPopoverTheme *)defaultTheme; - -// initialization - -- (id)initWithContentViewController:(UIViewController *)viewController; - -// theme - -- (void)beginThemeUpdates; -- (void)endThemeUpdates; - -// Present popover from classic views methods - -- (void)presentPopoverFromRect:(CGRect)rect - inView:(UIView *)view - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections - animated:(BOOL)animated; - -- (void)presentPopoverFromRect:(CGRect)rect - inView:(UIView *)view - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections - animated:(BOOL)animated - completion:(void (^)(void))completion; - -- (void)presentPopoverFromRect:(CGRect)rect - inView:(UIView *)view - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections - animated:(BOOL)animated - options:(WYPopoverAnimationOptions)options; - -- (void)presentPopoverFromRect:(CGRect)rect - inView:(UIView *)view - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections - animated:(BOOL)animated - options:(WYPopoverAnimationOptions)options - completion:(void (^)(void))completion; - -// Present popover from bar button items methods - -- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections - animated:(BOOL)animated; - -- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections - animated:(BOOL)animated - completion:(void (^)(void))completion; - -- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections - animated:(BOOL)animated - options:(WYPopoverAnimationOptions)options; - -- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections - animated:(BOOL)animated - options:(WYPopoverAnimationOptions)options - completion:(void (^)(void))completion; - -// Present popover as dialog methods - -- (void)presentPopoverAsDialogAnimated:(BOOL)animated; - -- (void)presentPopoverAsDialogAnimated:(BOOL)animated - completion:(void (^)(void))completion; - -- (void)presentPopoverAsDialogAnimated:(BOOL)animated - options:(WYPopoverAnimationOptions)options; - -- (void)presentPopoverAsDialogAnimated:(BOOL)animated - options:(WYPopoverAnimationOptions)options - completion:(void (^)(void))completion; - -// Dismiss popover methods - -- (void)dismissPopoverAnimated:(BOOL)animated; - -- (void)dismissPopoverAnimated:(BOOL)animated - completion:(void (^)(void))completion; - -- (void)dismissPopoverAnimated:(BOOL)animated - options:(WYPopoverAnimationOptions)aOptions; - -- (void)dismissPopoverAnimated:(BOOL)animated - options:(WYPopoverAnimationOptions)aOptions - completion:(void (^)(void))completion; - -// Misc - -- (void)setPopoverContentSize:(CGSize)size animated:(BOOL)animated; -- (void)performWithoutAnimation:(void (^)(void))aBlock; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@protocol WYPopoverControllerDelegate -@optional - -- (BOOL)popoverControllerShouldDismissPopover:(WYPopoverController *)popoverController; - -- (void)popoverControllerDidPresentPopover:(WYPopoverController *)popoverController; - -- (void)popoverControllerDidDismissPopover:(WYPopoverController *)popoverController; - -- (void)popoverController:(WYPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView **)view; - -- (BOOL)popoverControllerShouldIgnoreKeyboardBounds:(WYPopoverController *)popoverController; - -- (void)popoverController:(WYPopoverController *)popoverController willTranslatePopoverWithYOffset:(float *)value; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface WYPopoverTheme : NSObject - -// These two can be BOOLs, because implicit casting -// between BOOLs and NSUIntegers works fine -@property (nonatomic, assign) BOOL usesRoundedArrow; -@property (nonatomic, assign) BOOL dimsBackgroundViewsTintColor; - -@property (nonatomic, strong) UIColor *tintColor; -@property (nonatomic, strong) UIColor *fillTopColor; -@property (nonatomic, strong) UIColor *fillBottomColor; - -@property (nonatomic, strong) UIColor *glossShadowColor; -@property (nonatomic, assign) CGSize glossShadowOffset; -@property (nonatomic, assign) NSUInteger glossShadowBlurRadius; - -@property (nonatomic, assign) NSUInteger borderWidth; -@property (nonatomic, assign) NSUInteger arrowBase; -@property (nonatomic, assign) NSUInteger arrowHeight; - -@property (nonatomic, strong) UIColor *outerShadowColor; -@property (nonatomic, strong) UIColor *outerStrokeColor; -@property (nonatomic, assign) NSUInteger outerShadowBlurRadius; -@property (nonatomic, assign) CGSize outerShadowOffset; -@property (nonatomic, assign) NSUInteger outerCornerRadius; -@property (nonatomic, assign) NSUInteger minOuterCornerRadius; - -@property (nonatomic, strong) UIColor *innerShadowColor; -@property (nonatomic, strong) UIColor *innerStrokeColor; -@property (nonatomic, assign) NSUInteger innerShadowBlurRadius; -@property (nonatomic, assign) CGSize innerShadowOffset; -@property (nonatomic, assign) NSUInteger innerCornerRadius; - -@property (nonatomic, assign) UIEdgeInsets viewContentInsets; - -@property (nonatomic, strong) UIColor *overlayColor; - -@property (nonatomic) CGFloat preferredAlpha; - -+ (instancetype)theme; -+ (instancetype)themeForIOS6; -+ (instancetype)themeForIOS7; - -@end diff --git a/clients/ios/Other Sources/WYPopoverController/WYPopoverController.m b/clients/ios/Other Sources/WYPopoverController/WYPopoverController.m deleted file mode 100755 index 95b738b63..000000000 --- a/clients/ios/Other Sources/WYPopoverController/WYPopoverController.m +++ /dev/null @@ -1,2948 +0,0 @@ -/* - Version 0.3.6 - - WYPopoverController is available under the MIT license. - - Copyright © 2013 Nicolas CHENG - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#import "WYPopoverController.h" - -#import - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 -#define WY_BASE_SDK_7_ENABLED -#endif - -#ifdef DEBUG -#define WY_LOG(fmt, ...) NSLog((@"%s (%d) : " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__) -#else -#define WY_LOG(...) -#endif - -#define WY_IS_IOS_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) - -#define WY_IS_IOS_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) - -#define WY_IS_IOS_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) - -#define WY_IS_IOS_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface WYKeyboardListener : NSObject - -+ (BOOL)isVisible; -+ (CGRect)rect; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@implementation WYKeyboardListener - -static BOOL _isVisible; -static CGRect _keyboardRect; - -+ (void)load { - @autoreleasepool { - _keyboardRect = CGRectZero; - _isVisible = NO; - - [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; - [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(keyboardWillHide) name:UIKeyboardWillHideNotification object:nil]; - } -} - -+ (void)keyboardWillShow:(NSNotification *)notification { - NSDictionary *info = [notification userInfo]; - _keyboardRect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; - - _isVisible = YES; -} - -+ (void)keyboardWillHide { - _keyboardRect = CGRectZero; - _isVisible = NO; -} - -+ (BOOL)isVisible { - return _isVisible; -} - -+ (CGRect)rect { - return _keyboardRect; -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface UIColor (WYPopover) - -- (BOOL)wy_getValueOfRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)apha; -- (NSString *)wy_hexString; -- (UIColor *)wy_colorByLighten:(float)d; -- (UIColor *)wy_colorByDarken:(float)d; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@implementation UIColor (WYPopover) - -- (BOOL)wy_getValueOfRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha { - // model: kCGColorSpaceModelRGB, num_comps: 4 - // model: kCGColorSpaceModelMonochrome, num_comps: 2 - - CGColorSpaceRef colorSpace = CGColorSpaceRetain(CGColorGetColorSpace([self CGColor])); - CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); - CGColorSpaceRelease(colorSpace); - - CGFloat rFloat = 0.0, gFloat = 0.0, bFloat = 0.0, aFloat = 0.0; - BOOL result = NO; - - if (colorSpaceModel == kCGColorSpaceModelRGB) { - result = [self getRed:&rFloat green:&gFloat blue:&bFloat alpha:&aFloat]; - } else if (colorSpaceModel == kCGColorSpaceModelMonochrome) { - result = [self getWhite:&rFloat alpha:&aFloat]; - gFloat = rFloat; - bFloat = rFloat; - } - - if (red) *red = rFloat; - if (green) *green = gFloat; - if (blue) *blue = bFloat; - if (alpha) *alpha = aFloat; - - return result; -} - -- (NSString *)wy_hexString { - CGFloat rFloat, gFloat, bFloat, aFloat; - int r, g, b, a; - [self wy_getValueOfRed:&rFloat green:&gFloat blue:&bFloat alpha:&aFloat]; - - r = (int)(255.0 * rFloat); - g = (int)(255.0 * gFloat); - b = (int)(255.0 * bFloat); - a = (int)(255.0 * aFloat); - - return [NSString stringWithFormat:@"#%02x%02x%02x%02x", r, g, b, a]; -} - -- (UIColor *)wy_colorByLighten:(float)d { - CGFloat rFloat, gFloat, bFloat, aFloat; - [self wy_getValueOfRed:&rFloat green:&gFloat blue:&bFloat alpha:&aFloat]; - - return [UIColor colorWithRed:MIN(rFloat + d, 1.0) - green:MIN(gFloat + d, 1.0) - blue:MIN(bFloat + d, 1.0) - alpha:1.0]; -} - -- (UIColor *)wy_colorByDarken:(float)d { - CGFloat rFloat, gFloat, bFloat, aFloat; - [self wy_getValueOfRed:&rFloat green:&gFloat blue:&bFloat alpha:&aFloat]; - - return [UIColor colorWithRed:MAX(rFloat - d, 0.0) - green:MAX(gFloat - d, 0.0) - blue:MAX(bFloat - d, 0.0) - alpha:1.0]; -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface UINavigationController (WYPopover) - -@property(nonatomic, assign, getter = wy_isEmbedInPopover) BOOL wy_embedInPopover; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@implementation UINavigationController (WYPopover) - -static char const * const UINavigationControllerEmbedInPopoverTagKey = "UINavigationControllerEmbedInPopoverTagKey"; - -@dynamic wy_embedInPopover; - -+ (void)load { - Method original, swizzle; - - original = class_getInstanceMethod(self, @selector(pushViewController:animated:)); - swizzle = class_getInstanceMethod(self, @selector(sizzled_pushViewController:animated:)); - - method_exchangeImplementations(original, swizzle); - - original = class_getInstanceMethod(self, @selector(setViewControllers:animated:)); - swizzle = class_getInstanceMethod(self, @selector(sizzled_setViewControllers:animated:)); - - method_exchangeImplementations(original, swizzle); -} - -- (BOOL)wy_isEmbedInPopover { - BOOL result = NO; - - NSNumber *value = objc_getAssociatedObject(self, UINavigationControllerEmbedInPopoverTagKey); - - if (value) { - result = [value boolValue]; - } - - return result; -} - -- (void)setWy_embedInPopover:(BOOL)value -{ - objc_setAssociatedObject(self, UINavigationControllerEmbedInPopoverTagKey, [NSNumber numberWithBool:value], OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - -- (CGSize)contentSize:(UIViewController *)aViewController { - CGSize result = CGSizeZero; - -#pragma clang diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" - if ([aViewController respondsToSelector:@selector(contentSizeForViewInPopover)]) { - result = aViewController.contentSizeForViewInPopover; - } -#pragma clang diagnostic pop - -#ifdef WY_BASE_SDK_7_ENABLED - if ([aViewController respondsToSelector:@selector(preferredContentSize)]) { - result = aViewController.preferredContentSize; - } -#endif - - return result; -} - -- (void)setContentSize:(CGSize)aContentSize { -#pragma clang diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" - [self setContentSizeForViewInPopover:aContentSize]; -#pragma clang diagnostic pop - -#ifdef WY_BASE_SDK_7_ENABLED - if ([self respondsToSelector:@selector(setPreferredContentSize:)]) { - [self setPreferredContentSize:aContentSize]; - } -#endif -} - -- (void)sizzled_pushViewController:(UIViewController *)aViewController animated:(BOOL)aAnimated { - if (self.wy_isEmbedInPopover) { -#ifdef WY_BASE_SDK_7_ENABLED - if ([aViewController respondsToSelector:@selector(setEdgesForExtendedLayout:)]) { - aViewController.edgesForExtendedLayout = UIRectEdgeNone; - } -#endif - CGSize contentSize = [self contentSize:aViewController]; - [self setContentSize:contentSize]; - } - - [self sizzled_pushViewController:aViewController animated:aAnimated]; - - if (self.wy_isEmbedInPopover) { - CGSize contentSize = [self contentSize:aViewController]; - [self setContentSize:contentSize]; - } -} - -- (void)sizzled_setViewControllers:(NSArray *)aViewControllers animated:(BOOL)aAnimated { - NSUInteger count = [aViewControllers count]; - -#ifdef WY_BASE_SDK_7_ENABLED - if (self.wy_isEmbedInPopover && count > 0) { - for (UIViewController *viewController in aViewControllers) { - if ([viewController respondsToSelector:@selector(setEdgesForExtendedLayout:)]) { - viewController.edgesForExtendedLayout = UIRectEdgeNone; - } - } - } -#endif - - [self sizzled_setViewControllers:aViewControllers animated:aAnimated]; - - if (self.wy_isEmbedInPopover && count > 0) { - UIViewController *topViewController = [aViewControllers objectAtIndex:(count - 1)]; - CGSize contentSize = [self contentSize:topViewController]; - [self setContentSize:contentSize]; - } -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface UIViewController (WYPopover) -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@implementation UIViewController (WYPopover) - -+ (void)load { - Method original, swizzle; - -#pragma clang diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" - original = class_getInstanceMethod(self, @selector(setContentSizeForViewInPopover:)); - swizzle = class_getInstanceMethod(self, @selector(sizzled_setContentSizeForViewInPopover:)); - method_exchangeImplementations(original, swizzle); -#pragma clang diagnostic pop - -#ifdef WY_BASE_SDK_7_ENABLED - original = class_getInstanceMethod(self, @selector(setPreferredContentSize:)); - swizzle = class_getInstanceMethod(self, @selector(sizzled_setPreferredContentSize:)); - - if (original != NULL) { - method_exchangeImplementations(original, swizzle); - } -#endif -} - -- (void)sizzled_setContentSizeForViewInPopover:(CGSize)aSize { - [self sizzled_setContentSizeForViewInPopover:aSize]; - - if ([self isKindOfClass:[UINavigationController class]] == NO && self.navigationController != nil) { -#pragma clang diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" - [self.navigationController setContentSizeForViewInPopover:aSize]; -#pragma clang diagnostic pop - } -} - -- (void)sizzled_setPreferredContentSize:(CGSize)aSize { - [self sizzled_setPreferredContentSize:aSize]; - - if ([self isKindOfClass:[UINavigationController class]] == NO && self.navigationController != nil) - { -#ifdef WY_BASE_SDK_7_ENABLED - if ([self.navigationController wy_isEmbedInPopover] == NO) { - return; - } else if ([self respondsToSelector:@selector(setPreferredContentSize:)]) { - [self.navigationController sizzled_setPreferredContentSize:aSize]; - } -#endif - } -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface WYPopoverArea : NSObject - -@property (nonatomic, assign) WYPopoverArrowDirection arrowDirection; -@property (nonatomic, assign) CGSize areaSize; -@property (nonatomic, assign, readonly) float value; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma mark - WYPopoverArea - -@implementation WYPopoverArea - -- (NSString*)description { - const NSDictionary *directionMap = @{@(WYPopoverArrowDirectionUp) : @"UP", - @(WYPopoverArrowDirectionDown) : @"DOWN", - @(WYPopoverArrowDirectionLeft) : @"LEFT", - @(WYPopoverArrowDirectionRight) : @"RIGHT", - @(WYPopoverArrowDirectionNone) : @"NONE"}; - NSString *direction = directionMap[@(_arrowDirection)]; - return [NSString stringWithFormat:@"%@ [ %f x %f ]", direction, _areaSize.width, _areaSize.height]; -} - -- (float)value { - float result = 0; - - if (_areaSize.width > 0 && _areaSize.height > 0) { - float w1 = ceilf(_areaSize.width / 10.0); - float h1 = ceilf(_areaSize.height / 10.0); - - result = (w1 * h1); - } - - return result; -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface WYPopoverTheme () - -- (NSArray *)observableKeypaths; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@implementation WYPopoverTheme - -+ (id)theme { - - WYPopoverTheme *result = nil; - - if (WY_IS_IOS_LESS_THAN(@"7.0")) { - result = [WYPopoverTheme themeForIOS6]; - } else { - result = [WYPopoverTheme themeForIOS7]; - } - - return result; -} - -+ (id)themeForIOS6 { - - WYPopoverTheme *result = [[WYPopoverTheme alloc] init]; - - result.usesRoundedArrow = NO; - result.dimsBackgroundViewsTintColor = YES; - result.tintColor = [UIColor colorWithRed:55./255. green:63./255. blue:71./255. alpha:1.0]; - result.outerStrokeColor = nil; - result.innerStrokeColor = nil; - result.fillTopColor = result.tintColor; - result.fillBottomColor = [result.tintColor wy_colorByDarken:0.4]; - result.glossShadowColor = nil; - result.glossShadowOffset = CGSizeMake(0, 1.5); - result.glossShadowBlurRadius = 0; - result.borderWidth = 6; - result.arrowBase = 42; - result.arrowHeight = 18; - result.outerShadowColor = [UIColor colorWithWhite:0 alpha:0.75]; - result.outerShadowBlurRadius = 8; - result.outerShadowOffset = CGSizeMake(0, 2); - result.outerCornerRadius = 8; - result.minOuterCornerRadius = 0; - result.innerShadowColor = [UIColor colorWithWhite:0 alpha:0.75]; - result.innerShadowBlurRadius = 2; - result.innerShadowOffset = CGSizeMake(0, 1); - result.innerCornerRadius = 6; - result.viewContentInsets = UIEdgeInsetsMake(3, 0, 0, 0); - result.overlayColor = [UIColor clearColor]; - result.preferredAlpha = 1.0f; - - - return result; -} - -+ (id)themeForIOS7 { - - WYPopoverTheme *result = [[WYPopoverTheme alloc] init]; - - result.usesRoundedArrow = YES; - result.dimsBackgroundViewsTintColor = YES; - result.tintColor = [UIColor colorWithRed:244./255. green:244./255. blue:244./255. alpha:1.0]; - result.outerStrokeColor = [UIColor clearColor]; - result.innerStrokeColor = [UIColor clearColor]; - result.fillTopColor = nil; - result.fillBottomColor = nil; - result.glossShadowColor = nil; - result.glossShadowOffset = CGSizeZero; - result.glossShadowBlurRadius = 0; - result.borderWidth = 0; - result.arrowBase = 25; - result.arrowHeight = 13; - result.outerShadowColor = [UIColor clearColor]; - result.outerShadowBlurRadius = 0; - result.outerShadowOffset = CGSizeZero; - result.outerCornerRadius = 5; - result.minOuterCornerRadius = 0; - result.innerShadowColor = [UIColor clearColor]; - result.innerShadowBlurRadius = 0; - result.innerShadowOffset = CGSizeZero; - result.innerCornerRadius = 0; - result.viewContentInsets = UIEdgeInsetsZero; - result.overlayColor = [UIColor colorWithWhite:0 alpha:0.15]; - result.preferredAlpha = 1.0f; - - - return result; -} - -- (NSUInteger)innerCornerRadius { - float result = _innerCornerRadius; - - if (_borderWidth == 0) { - result = 0; - - if (_outerCornerRadius > 0) { - result = _outerCornerRadius; - } - } - - return result; -} - -- (CGSize)outerShadowOffset { - CGSize result = _outerShadowOffset; - - result.width = MIN(result.width, _outerShadowBlurRadius); - result.height = MIN(result.height, _outerShadowBlurRadius); - - return result; -} - -- (UIColor *)innerStrokeColor { - return _innerStrokeColor?: [self.fillTopColor wy_colorByDarken:0.6]; -} - -- (UIColor *)outerStrokeColor { - return _outerStrokeColor?: [self.fillTopColor wy_colorByDarken:0.6]; -} - -- (UIColor *)glossShadowColor { - return _glossShadowColor?: [self.fillTopColor wy_colorByLighten:0.2]; -} - -- (UIColor *)fillTopColor { - return _fillTopColor?: _tintColor; -} - -- (UIColor *)fillBottomColor { - return _fillBottomColor?: self.fillTopColor; -} - -- (NSArray *)observableKeypaths { - return [NSArray arrayWithObjects:@"tintColor", @"outerStrokeColor", @"innerStrokeColor", @"fillTopColor", @"fillBottomColor", @"glossShadowColor", @"glossShadowOffset", @"glossShadowBlurRadius", @"borderWidth", @"arrowBase", @"arrowHeight", @"outerShadowColor", @"outerShadowBlurRadius", @"outerShadowOffset", @"outerCornerRadius", @"innerShadowColor", @"innerShadowBlurRadius", @"innerShadowOffset", @"innerCornerRadius", @"viewContentInsets", @"overlayColor", nil]; -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface UIImage (WYPopover) - -+ (UIImage *)wy_imageWithColor:(UIColor *)color; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma mark - UIImage (WYPopover) - -@implementation UIImage (WYPopover) - -static float edgeSizeFromCornerRadius(float cornerRadius) { - return cornerRadius * 2 + 1; -} - -+ (UIImage *)wy_imageWithColor:(UIColor *)color { - return [self imageWithColor:color size:CGSizeMake(8, 8) cornerRadius:0]; -} - -+ (UIImage *)imageWithColor:(UIColor *)color - cornerRadius:(float)cornerRadius { - float min = edgeSizeFromCornerRadius(cornerRadius); - - CGSize minSize = CGSizeMake(min, min); - - return [self imageWithColor:color size:minSize cornerRadius:cornerRadius]; -} - -+ (UIImage *)imageWithColor:(UIColor *)color - size:(CGSize)aSize - cornerRadius:(float)cornerRadius { - CGRect rect = CGRectMake(0, 0, aSize.width, aSize.height); - UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius]; - roundedRect.lineWidth = 0; - UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0f); - [color setFill]; - [roundedRect fill]; - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return [image resizableImageWithCapInsets:UIEdgeInsetsMake(cornerRadius, cornerRadius, cornerRadius, cornerRadius)]; -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface WYPopoverBackgroundInnerView : UIView - -@property (nonatomic, strong) UIColor *innerStrokeColor; - -@property (nonatomic, strong) UIColor *gradientTopColor; -@property (nonatomic, strong) UIColor *gradientBottomColor; -@property (nonatomic, assign) float gradientHeight; -@property (nonatomic, assign) float gradientTopPosition; - -@property (nonatomic, strong) UIColor *innerShadowColor; -@property (nonatomic, assign) CGSize innerShadowOffset; -@property (nonatomic, assign) float innerShadowBlurRadius; -@property (nonatomic, assign) float innerCornerRadius; - -@property (nonatomic, assign) float navigationBarHeight; -@property (nonatomic, assign) BOOL wantsDefaultContentAppearance; -@property (nonatomic, assign) float borderWidth; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma mark - WYPopoverInnerView - -@implementation WYPopoverBackgroundInnerView - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - self.backgroundColor = [UIColor clearColor]; - self.userInteractionEnabled = NO; - } - return self; -} - -- (void)drawRect:(CGRect)rect { - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGContextRef context = UIGraphicsGetCurrentContext(); - - //// Gradient Declarations - NSArray* fillGradientColors = [NSArray arrayWithObjects: - (id)_gradientTopColor.CGColor, - (id)_gradientBottomColor.CGColor, nil]; - - CGFloat fillGradientLocations[2] = { 0, 1 }; - - CGGradientRef fillGradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)fillGradientColors, fillGradientLocations); - - //// innerRect Drawing - float barHeight = (_wantsDefaultContentAppearance == NO) ? _navigationBarHeight : 0; - float cornerRadius = (_wantsDefaultContentAppearance == NO) ? _innerCornerRadius : 0; - - CGRect innerRect = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect) + barHeight, CGRectGetWidth(rect) , CGRectGetHeight(rect) - barHeight); - - UIBezierPath* rectPath = [UIBezierPath bezierPathWithRect:innerRect]; - - UIBezierPath* roundedRectPath = [UIBezierPath bezierPathWithRoundedRect:innerRect cornerRadius:cornerRadius + 1]; - - if (_wantsDefaultContentAppearance == NO && _borderWidth > 0) { - CGContextSaveGState(context); - { - [rectPath appendPath:roundedRectPath]; - rectPath.usesEvenOddFillRule = YES; - [rectPath addClip]; - - CGContextDrawLinearGradient(context, fillGradient, - CGPointMake(0, -_gradientTopPosition), - CGPointMake(0, -_gradientTopPosition + _gradientHeight), - 0); - } - CGContextRestoreGState(context); - } - - CGContextSaveGState(context); - { - if (_wantsDefaultContentAppearance == NO && _borderWidth > 0) { - [roundedRectPath addClip]; - CGContextSetShadowWithColor(context, _innerShadowOffset, _innerShadowBlurRadius, _innerShadowColor.CGColor); - } - - UIBezierPath* inRoundedRectPath = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(innerRect, 0.5, 0.5) cornerRadius:cornerRadius]; - - if (_borderWidth == 0) { - inRoundedRectPath = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(innerRect, 0.5, 0.5) byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:CGSizeMake(cornerRadius, cornerRadius)]; - } - - [self.innerStrokeColor setStroke]; - inRoundedRectPath.lineWidth = 1; - [inRoundedRectPath stroke]; - } - - CGContextRestoreGState(context); - - CGGradientRelease(fillGradient); - CGColorSpaceRelease(colorSpace); -} - -- (void)dealloc -{ - _innerShadowColor = nil; - _innerStrokeColor = nil; - _gradientTopColor = nil; - _gradientBottomColor = nil; -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@protocol WYPopoverOverlayViewDelegate; - -@interface WYPopoverOverlayView : UIView { - BOOL _testHits; -} - -@property(nonatomic, assign) id delegate; -@property(nonatomic, unsafe_unretained) NSArray *passthroughViews; - -@end - - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma mark - WYPopoverOverlayViewDelegate - -@protocol WYPopoverOverlayViewDelegate - -@optional -- (BOOL)dismissOnPassthroughViewTap; -- (void)popoverOverlayViewDidTouch:(WYPopoverOverlayView *)overlayView; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma mark - WYPopoverOverlayView - -@implementation WYPopoverOverlayView - -- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { - if (_testHits) { - return nil; - } - - UIView *view = [super hitTest:point withEvent:event]; - - if (view == self) { - _testHits = YES; - UIView *superHitView = [self.superview hitTest:point withEvent:event]; - _testHits = NO; - - if ([self isPassthroughView:superHitView]) { - if ([self.delegate dismissOnPassthroughViewTap]) { - dispatch_async(dispatch_get_main_queue(), ^ { - if ([self.delegate respondsToSelector:@selector(popoverOverlayViewDidTouch:)]) { - [self.delegate popoverOverlayViewDidTouch:self]; - } - }); - } - return superHitView; - } - } - return view; -} - -- (BOOL)isPassthroughView:(UIView *)view { - if (view == nil) { - return NO; - } - if ([self.passthroughViews containsObject:view]) { - return YES; - } - return [self isPassthroughView:view.superview]; -} - -/** - * @note This empty method is meaningful. - * If the method is not defined, touch event isn't capture in iOS6. - */ -- (void)drawRect:(CGRect)rect {} - -#pragma mark - UIAccessibility - -- (void)accessibilityElementDidBecomeFocused { - self.accessibilityLabel = NSLocalizedString(@"Double-tap to dismiss pop-up window.", nil); -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma mark - WYPopoverBackgroundViewDelegate - -@protocol WYPopoverBackgroundViewDelegate - -@optional -- (void)popoverBackgroundViewDidTouchOutside:(WYPopoverBackgroundView *)backgroundView; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -@interface WYPopoverBackgroundView () { - WYPopoverBackgroundInnerView *_innerView; - CGSize _contentSize; -} - -@property(nonatomic, assign) id delegate; - -@property (nonatomic, assign) WYPopoverArrowDirection arrowDirection; - -@property (nonatomic, strong, readonly) UIView *contentView; -@property (nonatomic, assign, readonly) float navigationBarHeight; -@property (nonatomic, assign, readonly) UIEdgeInsets outerShadowInsets; -@property (nonatomic, assign) float arrowOffset; -@property (nonatomic, assign) BOOL wantsDefaultContentAppearance; - -@property (nonatomic, assign, getter = isAppearing) BOOL appearing; - -- (void)tapOut; - -- (void)setViewController:(UIViewController *)viewController; - -- (CGRect)outerRect; -- (CGRect)innerRect; -- (CGRect)arrowRect; - -- (CGRect)outerRect:(CGRect)rect arrowDirection:(WYPopoverArrowDirection)aArrowDirection; -- (CGRect)innerRect:(CGRect)rect arrowDirection:(WYPopoverArrowDirection)aArrowDirection; -- (CGRect)arrowRect:(CGRect)rect arrowDirection:(WYPopoverArrowDirection)aArrowDirection; - -- (id)initWithContentSize:(CGSize)contentSize; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma mark - WYPopoverBackgroundView - -@implementation WYPopoverBackgroundView - -- (id)initWithContentSize:(CGSize)aContentSize { - self = [super initWithFrame:CGRectMake(0, 0, aContentSize.width, aContentSize.height)]; - - if (self != nil) { - _contentSize = aContentSize; - - self.autoresizesSubviews = NO; - self.backgroundColor = [UIColor clearColor]; - - self.arrowDirection = WYPopoverArrowDirectionDown; - self.arrowOffset = 0; - - self.layer.name = @"parent"; - - if (WY_IS_IOS_GREATER_THAN_OR_EQUAL_TO(@"6.0")) { - self.layer.drawsAsynchronously = YES; - } - - self.layer.contentsScale = [UIScreen mainScreen].scale; - //self.layer.edgeAntialiasingMask = kCALayerLeftEdge | kCALayerRightEdge | kCALayerBottomEdge | kCALayerTopEdge; - self.layer.delegate = self; - } - - return self; -} - -- (void)tapOut { - [self.delegate popoverBackgroundViewDidTouchOutside:self]; -} - -- (UIEdgeInsets)outerShadowInsets { - UIEdgeInsets result = UIEdgeInsetsMake(_outerShadowBlurRadius, _outerShadowBlurRadius, _outerShadowBlurRadius, _outerShadowBlurRadius); - - result.top -= self.outerShadowOffset.height; - result.bottom += self.outerShadowOffset.height; - result.left -= self.outerShadowOffset.width; - result.right += self.outerShadowOffset.width; - - return result; -} - -- (void)setArrowOffset:(float)value { - float coef = 1; - - if (value != 0) { - coef = value / ABS(value); - - value = ABS(value); - - CGRect outerRect = [self outerRect]; - - float delta = self.arrowBase / 2. + .5; - - delta += MIN(_minOuterCornerRadius, _outerCornerRadius); - - outerRect = CGRectInset(outerRect, delta, delta); - - if (_arrowDirection == WYPopoverArrowDirectionUp || _arrowDirection == WYPopoverArrowDirectionDown) { - value += coef * self.outerShadowOffset.width; - value = MIN(value, CGRectGetWidth(outerRect) / 2); - } - - if (_arrowDirection == WYPopoverArrowDirectionLeft || _arrowDirection == WYPopoverArrowDirectionRight) { - value += coef * self.outerShadowOffset.height; - value = MIN(value, CGRectGetHeight(outerRect) / 2); - } - } else { - if (_arrowDirection == WYPopoverArrowDirectionUp || _arrowDirection == WYPopoverArrowDirectionDown) { - value += self.outerShadowOffset.width; - } - - if (_arrowDirection == WYPopoverArrowDirectionLeft || _arrowDirection == WYPopoverArrowDirectionRight) { - value += self.outerShadowOffset.height; - } - } - _arrowOffset = value * coef; -} - -- (void)setViewController:(UIViewController *)viewController { - _contentView = viewController.view; - - _contentView.frame = CGRectIntegral(CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)); - - [self addSubview:_contentView]; - - _navigationBarHeight = 0; - - if ([viewController isKindOfClass:[UINavigationController class]]) { - UINavigationController* navigationController = (UINavigationController*)viewController; - _navigationBarHeight = navigationController.navigationBarHidden? 0 : navigationController.navigationBar.bounds.size.height; - } - - _contentView.frame = CGRectIntegral([self innerRect]); - - if (_innerView == nil) { - _innerView = [[WYPopoverBackgroundInnerView alloc] initWithFrame:_contentView.frame]; - _innerView.userInteractionEnabled = NO; - - _innerView.gradientTopColor = self.fillTopColor; - _innerView.gradientBottomColor = self.fillBottomColor; - _innerView.innerShadowColor = _innerShadowColor; - _innerView.innerStrokeColor = self.innerStrokeColor; - _innerView.innerShadowOffset = _innerShadowOffset; - _innerView.innerCornerRadius = self.innerCornerRadius; - _innerView.innerShadowBlurRadius = _innerShadowBlurRadius; - _innerView.borderWidth = self.borderWidth; - } - - _innerView.navigationBarHeight = _navigationBarHeight; - _innerView.gradientHeight = self.frame.size.height - 2 * _outerShadowBlurRadius; - _innerView.gradientTopPosition = _contentView.frame.origin.y - self.outerShadowInsets.top; - _innerView.wantsDefaultContentAppearance = _wantsDefaultContentAppearance; - - [self insertSubview:_innerView aboveSubview:_contentView]; - - _innerView.frame = CGRectIntegral(_contentView.frame); - - [self.layer setNeedsDisplay]; -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGSize result = size; - - result.width += 2 * (_borderWidth + _outerShadowBlurRadius); - result.height += _borderWidth + 2 * _outerShadowBlurRadius; - - if (_navigationBarHeight == 0) { - result.height += _borderWidth; - } - - if (_arrowDirection == WYPopoverArrowDirectionUp || _arrowDirection == WYPopoverArrowDirectionDown) { - result.height += _arrowHeight; - } - - if (_arrowDirection == WYPopoverArrowDirectionLeft || _arrowDirection == WYPopoverArrowDirectionRight) { - result.width += _arrowHeight; - } - - return result; -} - -- (void)sizeToFit { - CGSize size = [self sizeThatFits:_contentSize]; - self.bounds = CGRectMake(0, 0, size.width, size.height); -} - -#pragma mark Drawing - -- (void)setNeedsDisplay { - [super setNeedsDisplay]; - - [self.layer setNeedsDisplay]; - - self.alpha = self.preferredAlpha; - - if (_innerView) { - _innerView.gradientTopColor = self.fillTopColor; - _innerView.gradientBottomColor = self.fillBottomColor; - _innerView.innerShadowColor = _innerShadowColor; - _innerView.innerStrokeColor = self.innerStrokeColor; - _innerView.innerShadowOffset = _innerShadowOffset; - _innerView.innerCornerRadius = self.innerCornerRadius; - _innerView.innerShadowBlurRadius = _innerShadowBlurRadius; - _innerView.borderWidth = self.borderWidth; - - _innerView.navigationBarHeight = _navigationBarHeight; - _innerView.gradientHeight = self.frame.size.height - 2 * _outerShadowBlurRadius; - _innerView.gradientTopPosition = _contentView.frame.origin.y - self.outerShadowInsets.top; - _innerView.wantsDefaultContentAppearance = _wantsDefaultContentAppearance; - - [_innerView setNeedsDisplay]; - } -} - -#pragma mark CALayerDelegate - -- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context { - if ([layer.name isEqualToString:@"parent"]) { - UIGraphicsPushContext(context); - //CGContextSetShouldAntialias(context, YES); - //CGContextSetAllowsAntialiasing(context, YES); - - //// General Declarations - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - - //// Gradient Declarations - NSArray* fillGradientColors = [NSArray arrayWithObjects: - (id)self.fillTopColor.CGColor, - (id)self.fillBottomColor.CGColor, nil]; - - CGFloat fillGradientLocations[2] = {0, 1}; - CGGradientRef fillGradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)fillGradientColors, fillGradientLocations); - - // Frames - CGRect rect = self.bounds; - - CGRect outerRect = [self outerRect:rect arrowDirection:self.arrowDirection]; - CGRect insetRect = CGRectInset(outerRect, 0.5, 0.5); - if (!CGRectIsEmpty(insetRect) && !CGRectIsInfinite(insetRect)) { - outerRect = insetRect; - } - - // Inner Path - CGMutablePathRef outerPathRef = CGPathCreateMutable(); - - CGPoint arrowTipPoint = CGPointZero; - CGPoint arrowBasePointA = CGPointZero; - CGPoint arrowBasePointB = CGPointZero; - - float reducedOuterCornerRadius = 0; - - if (_arrowDirection == WYPopoverArrowDirectionUp || _arrowDirection == WYPopoverArrowDirectionDown) { - if (_arrowOffset >= 0) { - reducedOuterCornerRadius = CGRectGetMaxX(outerRect) - (CGRectGetMidX(outerRect) + _arrowOffset + _arrowBase / 2); - } else { - reducedOuterCornerRadius = (CGRectGetMidX(outerRect) + _arrowOffset - _arrowBase / 2) - CGRectGetMinX(outerRect); - } - } else if (_arrowDirection == WYPopoverArrowDirectionLeft || _arrowDirection == WYPopoverArrowDirectionRight) { - if (_arrowOffset >= 0) { - reducedOuterCornerRadius = CGRectGetMaxY(outerRect) - (CGRectGetMidY(outerRect) + _arrowOffset + _arrowBase / 2); - } else { - reducedOuterCornerRadius = (CGRectGetMidY(outerRect) + _arrowOffset - _arrowBase / 2) - CGRectGetMinY(outerRect); - } - } - - reducedOuterCornerRadius = MIN(reducedOuterCornerRadius, _outerCornerRadius); - - CGFloat roundedArrowControlLength = _arrowBase / 5.0f; - if (_arrowDirection == WYPopoverArrowDirectionUp) { - arrowTipPoint = CGPointMake(CGRectGetMidX(outerRect) + _arrowOffset, - CGRectGetMinY(outerRect) - _arrowHeight); - arrowBasePointA = CGPointMake(arrowTipPoint.x - _arrowBase / 2, - arrowTipPoint.y + _arrowHeight); - arrowBasePointB = CGPointMake(arrowTipPoint.x + _arrowBase / 2, - arrowTipPoint.y + _arrowHeight); - - CGPathMoveToPoint(outerPathRef, NULL, arrowBasePointA.x, arrowBasePointA.y); - - if (self.usesRoundedArrow) { - CGPathAddCurveToPoint(outerPathRef, NULL, - arrowBasePointA.x + roundedArrowControlLength, arrowBasePointA.y, - arrowTipPoint.x - (roundedArrowControlLength * 0.75f), arrowTipPoint.y, - arrowTipPoint.x, arrowTipPoint.y); - CGPathAddCurveToPoint(outerPathRef, NULL, - arrowTipPoint.x + (roundedArrowControlLength * 0.75f), arrowTipPoint.y, - arrowBasePointB.x - roundedArrowControlLength, arrowBasePointB.y, - arrowBasePointB.x, arrowBasePointB.y); - } else { - CGPathAddLineToPoint(outerPathRef, NULL, arrowTipPoint.x, arrowTipPoint.y); - CGPathAddLineToPoint(outerPathRef, NULL, arrowBasePointB.x, arrowBasePointB.y); - } - - CGPathAddArcToPoint(outerPathRef, NULL, CGRectGetMaxX(outerRect), CGRectGetMinY(outerRect), - CGRectGetMaxX(outerRect), CGRectGetMaxY(outerRect), - (_arrowOffset >= 0) ? reducedOuterCornerRadius : _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, CGRectGetMaxX(outerRect), CGRectGetMaxY(outerRect), - CGRectGetMinX(outerRect), CGRectGetMaxY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, CGRectGetMinX(outerRect), CGRectGetMaxY(outerRect), - CGRectGetMinX(outerRect), CGRectGetMinY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, CGRectGetMinX(outerRect), CGRectGetMinY(outerRect), - CGRectGetMaxX(outerRect), CGRectGetMinY(outerRect), - (_arrowOffset < 0) ? reducedOuterCornerRadius : _outerCornerRadius); - - CGPathAddLineToPoint(outerPathRef, NULL, arrowBasePointA.x, arrowBasePointA.y); - } else if (_arrowDirection == WYPopoverArrowDirectionDown) { - arrowTipPoint = CGPointMake(CGRectGetMidX(outerRect) + _arrowOffset, - CGRectGetMaxY(outerRect) + _arrowHeight); - arrowBasePointA = CGPointMake(arrowTipPoint.x + _arrowBase / 2, - arrowTipPoint.y - _arrowHeight); - arrowBasePointB = CGPointMake(arrowTipPoint.x - _arrowBase / 2, - arrowTipPoint.y - _arrowHeight); - - CGPathMoveToPoint(outerPathRef, NULL, arrowBasePointA.x, arrowBasePointA.y); - - if (self.usesRoundedArrow) { - CGPathAddCurveToPoint(outerPathRef, NULL, - arrowBasePointA.x - roundedArrowControlLength, arrowBasePointA.y, - arrowTipPoint.x + (roundedArrowControlLength * 0.75f), arrowTipPoint.y, - arrowTipPoint.x, arrowTipPoint.y); - CGPathAddCurveToPoint(outerPathRef, NULL, - arrowTipPoint.x - (roundedArrowControlLength * 0.75f), arrowTipPoint.y, - arrowBasePointB.x + roundedArrowControlLength, arrowBasePointA.y, - arrowBasePointB.x, arrowBasePointB.y); - } else { - CGPathAddLineToPoint(outerPathRef, NULL, arrowTipPoint.x, arrowTipPoint.y); - CGPathAddLineToPoint(outerPathRef, NULL, arrowBasePointB.x, arrowBasePointB.y); - } - - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMinX(outerRect), CGRectGetMaxY(outerRect), - CGRectGetMinX(outerRect), CGRectGetMinY(outerRect), - (_arrowOffset < 0) ? reducedOuterCornerRadius : _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMinX(outerRect), CGRectGetMinY(outerRect), - CGRectGetMaxX(outerRect), CGRectGetMinY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMaxX(outerRect), CGRectGetMinY(outerRect), - CGRectGetMaxX(outerRect), CGRectGetMaxY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMaxX(outerRect), CGRectGetMaxY(outerRect), - CGRectGetMinX(outerRect), CGRectGetMaxY(outerRect), - (_arrowOffset >= 0) ? reducedOuterCornerRadius : _outerCornerRadius); - - CGPathAddLineToPoint(outerPathRef, NULL, arrowBasePointA.x, arrowBasePointA.y); - } else if (_arrowDirection == WYPopoverArrowDirectionLeft) { - arrowTipPoint = CGPointMake(CGRectGetMinX(outerRect) - _arrowHeight, - CGRectGetMidY(outerRect) + _arrowOffset); - arrowBasePointA = CGPointMake(arrowTipPoint.x + _arrowHeight, - arrowTipPoint.y + _arrowBase / 2); - arrowBasePointB = CGPointMake(arrowTipPoint.x + _arrowHeight, - arrowTipPoint.y - _arrowBase / 2); - - CGPathMoveToPoint(outerPathRef, NULL, arrowBasePointA.x, arrowBasePointA.y); - - if (self.usesRoundedArrow) { - CGPathAddCurveToPoint(outerPathRef, NULL, - arrowBasePointA.x, arrowBasePointA.y - roundedArrowControlLength, - arrowTipPoint.x, arrowTipPoint.y + (roundedArrowControlLength * 0.75f), - arrowTipPoint.x, arrowTipPoint.y); - CGPathAddCurveToPoint(outerPathRef, NULL, - arrowTipPoint.x, arrowTipPoint.y - (roundedArrowControlLength * 0.75f), - arrowBasePointB.x, arrowBasePointB.y + roundedArrowControlLength, - arrowBasePointB.x, arrowBasePointB.y); - } else { - CGPathAddLineToPoint(outerPathRef, NULL, arrowTipPoint.x, arrowTipPoint.y); - CGPathAddLineToPoint(outerPathRef, NULL, arrowBasePointB.x, arrowBasePointB.y); - } - - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMinX(outerRect), CGRectGetMinY(outerRect), - CGRectGetMaxX(outerRect), CGRectGetMinY(outerRect), - (_arrowOffset < 0) ? reducedOuterCornerRadius : _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMaxX(outerRect), CGRectGetMinY(outerRect), - CGRectGetMaxX(outerRect), CGRectGetMaxY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMaxX(outerRect), CGRectGetMaxY(outerRect), - CGRectGetMinX(outerRect), CGRectGetMaxY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMinX(outerRect), CGRectGetMaxY(outerRect), - CGRectGetMinX(outerRect), CGRectGetMinY(outerRect), - (_arrowOffset >= 0) ? reducedOuterCornerRadius : _outerCornerRadius); - - CGPathAddLineToPoint(outerPathRef, NULL, arrowBasePointA.x, arrowBasePointA.y); - } else if (_arrowDirection == WYPopoverArrowDirectionRight) { - arrowTipPoint = CGPointMake(CGRectGetMaxX(outerRect) + _arrowHeight, - CGRectGetMidY(outerRect) + _arrowOffset); - arrowBasePointA = CGPointMake(arrowTipPoint.x - _arrowHeight, - arrowTipPoint.y - _arrowBase / 2); - arrowBasePointB = CGPointMake(arrowTipPoint.x - _arrowHeight, - arrowTipPoint.y + _arrowBase / 2); - - CGPathMoveToPoint(outerPathRef, NULL, arrowBasePointA.x, arrowBasePointA.y); - - if (self.usesRoundedArrow) { - CGPathAddCurveToPoint(outerPathRef, NULL, - arrowBasePointA.x, arrowBasePointA.y + roundedArrowControlLength, - arrowTipPoint.x, arrowTipPoint.y - (roundedArrowControlLength * 0.75f), - arrowTipPoint.x, arrowTipPoint.y); - CGPathAddCurveToPoint(outerPathRef, NULL, - arrowTipPoint.x, arrowTipPoint.y + (roundedArrowControlLength * 0.75f), - arrowBasePointB.x, arrowBasePointB.y - roundedArrowControlLength, - arrowBasePointB.x, arrowBasePointB.y); - } else { - CGPathAddLineToPoint(outerPathRef, NULL, arrowTipPoint.x, arrowTipPoint.y); - CGPathAddLineToPoint(outerPathRef, NULL, arrowBasePointB.x, arrowBasePointB.y); - } - - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMaxX(outerRect), CGRectGetMaxY(outerRect), - CGRectGetMinX(outerRect), CGRectGetMaxY(outerRect), - (_arrowOffset >= 0) ? reducedOuterCornerRadius : _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMinX(outerRect), CGRectGetMaxY(outerRect), - CGRectGetMinX(outerRect), CGRectGetMinY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMinX(outerRect), CGRectGetMinY(outerRect), - CGRectGetMaxX(outerRect), CGRectGetMinY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMaxX(outerRect), CGRectGetMinY(outerRect), - CGRectGetMaxX(outerRect), CGRectGetMaxY(outerRect), - (_arrowOffset < 0) ? reducedOuterCornerRadius : _outerCornerRadius); - - CGPathAddLineToPoint(outerPathRef, NULL, arrowBasePointA.x, arrowBasePointA.y); - } else if (_arrowDirection == WYPopoverArrowDirectionNone) { - CGPoint origin = CGPointMake(CGRectGetMaxX(outerRect), CGRectGetMidY(outerRect)); - - CGPathMoveToPoint(outerPathRef, NULL, origin.x, origin.y); - - CGPathAddLineToPoint(outerPathRef, NULL, CGRectGetMaxX(outerRect), CGRectGetMidY(outerRect)); - CGPathAddLineToPoint(outerPathRef, NULL, CGRectGetMaxX(outerRect), CGRectGetMidY(outerRect)); - - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMaxX(outerRect), CGRectGetMaxY(outerRect), - CGRectGetMinX(outerRect), CGRectGetMaxY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMinX(outerRect), CGRectGetMaxY(outerRect), - CGRectGetMinX(outerRect), CGRectGetMinY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMinX(outerRect), CGRectGetMinY(outerRect), - CGRectGetMaxX(outerRect), CGRectGetMinY(outerRect), - _outerCornerRadius); - CGPathAddArcToPoint(outerPathRef, NULL, - CGRectGetMaxX(outerRect), CGRectGetMinY(outerRect), - CGRectGetMaxX(outerRect), CGRectGetMaxY(outerRect), - _outerCornerRadius); - - CGPathAddLineToPoint(outerPathRef, NULL, origin.x, origin.y); - } - - CGPathCloseSubpath(outerPathRef); - UIBezierPath* outerRectPath = [UIBezierPath bezierPathWithCGPath:outerPathRef]; - - CGContextSaveGState(context); - { - CGContextSetShadowWithColor(context, self.outerShadowOffset, _outerShadowBlurRadius, _outerShadowColor.CGColor); - CGContextBeginTransparencyLayer(context, NULL); - [outerRectPath addClip]; - CGRect outerRectBounds = CGPathGetPathBoundingBox(outerRectPath.CGPath); - CGContextDrawLinearGradient(context, fillGradient, - CGPointMake(CGRectGetMidX(outerRectBounds), CGRectGetMinY(outerRectBounds)), - CGPointMake(CGRectGetMidX(outerRectBounds), CGRectGetMaxY(outerRectBounds)), - 0); - CGContextEndTransparencyLayer(context); - } - CGContextRestoreGState(context); - - ////// outerRect Inner Shadow - CGRect outerRectBorderRect = CGRectInset([outerRectPath bounds], -_glossShadowBlurRadius, -_glossShadowBlurRadius); - outerRectBorderRect = CGRectOffset(outerRectBorderRect, -_glossShadowOffset.width, -_glossShadowOffset.height); - outerRectBorderRect = CGRectInset(CGRectUnion(outerRectBorderRect, [outerRectPath bounds]), -1, -1); - - UIBezierPath* outerRectNegativePath = [UIBezierPath bezierPathWithRect: outerRectBorderRect]; - [outerRectNegativePath appendPath: outerRectPath]; - outerRectNegativePath.usesEvenOddFillRule = YES; - - CGContextSaveGState(context); - { - float xOffset = _glossShadowOffset.width + round(outerRectBorderRect.size.width); - float yOffset = _glossShadowOffset.height; - CGContextSetShadowWithColor(context, - CGSizeMake(xOffset + copysign(0.1, xOffset), yOffset + copysign(0.1, yOffset)), - _glossShadowBlurRadius, - self.glossShadowColor.CGColor); - - [outerRectPath addClip]; - CGAffineTransform transform = CGAffineTransformMakeTranslation(-round(outerRectBorderRect.size.width), 0); - [outerRectNegativePath applyTransform: transform]; - [[UIColor grayColor] setFill]; - [outerRectNegativePath fill]; - } - CGContextRestoreGState(context); - - [self.outerStrokeColor setStroke]; - outerRectPath.lineWidth = 1; - [outerRectPath stroke]; - - //// Cleanup - CFRelease(outerPathRef); - CGGradientRelease(fillGradient); - CGColorSpaceRelease(colorSpace); - - UIGraphicsPopContext(); - } -} - -#pragma mark Private - -- (CGRect)outerRect { - return [self outerRect:self.bounds arrowDirection:self.arrowDirection]; -} - -- (CGRect)innerRect { - return [self innerRect:self.bounds arrowDirection:self.arrowDirection]; -} - -- (CGRect)arrowRect { - return [self arrowRect:self.bounds arrowDirection:self.arrowDirection]; -} - -- (CGRect)outerRect:(CGRect)rect arrowDirection:(WYPopoverArrowDirection)aArrowDirection{ - CGRect result = rect; - - if (aArrowDirection == WYPopoverArrowDirectionUp || _arrowDirection == WYPopoverArrowDirectionDown) { - result.size.height -= _arrowHeight; - - if (aArrowDirection == WYPopoverArrowDirectionUp) { - result = CGRectOffset(result, 0, _arrowHeight); - } - } - - if (aArrowDirection == WYPopoverArrowDirectionLeft || _arrowDirection == WYPopoverArrowDirectionRight) { - result.size.width -= _arrowHeight; - - if (aArrowDirection == WYPopoverArrowDirectionLeft) { - result = CGRectOffset(result, _arrowHeight, 0); - } - } - - result = CGRectInset(result, _outerShadowBlurRadius, _outerShadowBlurRadius); - result.origin.x -= self.outerShadowOffset.width; - result.origin.y -= self.outerShadowOffset.height; - - return result; -} - -- (CGRect)innerRect:(CGRect)rect arrowDirection:(WYPopoverArrowDirection)aArrowDirection { - CGRect result = [self outerRect:rect arrowDirection:aArrowDirection]; - - result.origin.x += _borderWidth; - result.origin.y += 0; - result.size.width -= 2 * _borderWidth; - result.size.height -= _borderWidth; - - if (_navigationBarHeight == 0 || _wantsDefaultContentAppearance) { - result.origin.y += _borderWidth; - result.size.height -= _borderWidth; - } - - result.origin.x += _viewContentInsets.left; - result.origin.y += _viewContentInsets.top; - result.size.width = result.size.width - _viewContentInsets.left - _viewContentInsets.right; - result.size.height = result.size.height - _viewContentInsets.top - _viewContentInsets.bottom; - - if (_borderWidth > 0) { - result = CGRectInset(result, -1, -1); - } - - return result; -} - -- (CGRect)arrowRect:(CGRect)rect arrowDirection:(WYPopoverArrowDirection)aArrowDirection { - CGRect result = CGRectZero; - - if (_arrowHeight > 0) { - result.size = CGSizeMake(_arrowBase, _arrowHeight); - - if (aArrowDirection == WYPopoverArrowDirectionLeft || _arrowDirection == WYPopoverArrowDirectionRight) { - result.size = CGSizeMake(_arrowHeight, _arrowBase); - } - - CGRect outerRect = [self outerRect:rect arrowDirection:aArrowDirection]; - - if (aArrowDirection == WYPopoverArrowDirectionDown) { - result.origin.x = CGRectGetMidX(outerRect) - result.size.width / 2 + _arrowOffset; - result.origin.y = CGRectGetMaxY(outerRect); - } - - if (aArrowDirection == WYPopoverArrowDirectionUp) { - result.origin.x = CGRectGetMidX(outerRect) - result.size.width / 2 + _arrowOffset; - result.origin.y = CGRectGetMinY(outerRect) - result.size.height; - } - - if (aArrowDirection == WYPopoverArrowDirectionRight) { - result.origin.x = CGRectGetMaxX(outerRect); - result.origin.y = CGRectGetMidY(outerRect) - result.size.height / 2 + _arrowOffset; - } - - if (aArrowDirection == WYPopoverArrowDirectionLeft) { - result.origin.x = CGRectGetMinX(outerRect) - result.size.width; - result.origin.y = CGRectGetMidY(outerRect) - result.size.height / 2 + _arrowOffset; - } - } - - return result; -} - -#pragma mark Memory Management - -- (void)dealloc { - _contentView = nil; - _innerView = nil; - _tintColor = nil; - _outerStrokeColor = nil; - _innerStrokeColor = nil; - _fillTopColor = nil; - _fillBottomColor = nil; - _glossShadowColor = nil; - _outerShadowColor = nil; - _innerShadowColor = nil; -} - -@end - -//////////////////////////////////////////////////////////////////////////// - -@interface WYPopoverController () { - UIViewController *_viewController; - CGRect _rect; - UIView *_inView; - WYPopoverOverlayView *_overlayView; - WYPopoverBackgroundView *_backgroundView; - WYPopoverArrowDirection _permittedArrowDirections; - BOOL _animated; - BOOL _isListeningNotifications; - BOOL _isObserverAdded; - BOOL _isInterfaceOrientationChanging; - BOOL _ignoreOrientation; - __weak UIBarButtonItem *_barButtonItem; - - WYPopoverAnimationOptions options; - - BOOL themeUpdatesEnabled; - BOOL themeIsUpdating; -} - -- (void)dismissPopoverAnimated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aAptions - completion:(void (^)(void))aCompletion - callDelegate:(BOOL)aCallDelegate; - -- (WYPopoverArrowDirection)arrowDirectionForRect:(CGRect)aRect - inView:(UIView*)aView - contentSize:(CGSize)aContentSize - arrowHeight:(float)aArrowHeight - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections; - -- (CGSize)sizeForRect:(CGRect)aRect - inView:(UIView *)aView - arrowHeight:(float)aArrowHeight - arrowDirection:(WYPopoverArrowDirection)aArrowDirection; - -- (void)registerTheme; -- (void)unregisterTheme; -- (void)updateThemeUI; - -- (CGSize)topViewControllerContentSize; - -@end - -//////////////////////////////////////////////////////////////////////////// - -#pragma mark - WYPopoverController - -@implementation WYPopoverController - -static WYPopoverTheme *defaultTheme_ = nil; - -@synthesize popoverContentSize = popoverContentSize_; - -+ (void)setDefaultTheme:(WYPopoverTheme *)aTheme { - defaultTheme_ = aTheme; - - @autoreleasepool { - WYPopoverBackgroundView *appearance = [WYPopoverBackgroundView appearance]; - appearance.usesRoundedArrow = aTheme.usesRoundedArrow; - appearance.dimsBackgroundViewsTintColor = aTheme.dimsBackgroundViewsTintColor; - appearance.tintColor = aTheme.tintColor; - appearance.outerStrokeColor = aTheme.outerStrokeColor; - appearance.innerStrokeColor = aTheme.innerStrokeColor; - appearance.fillTopColor = aTheme.fillTopColor; - appearance.fillBottomColor = aTheme.fillBottomColor; - appearance.glossShadowColor = aTheme.glossShadowColor; - appearance.glossShadowOffset = aTheme.glossShadowOffset; - appearance.glossShadowBlurRadius = aTheme.glossShadowBlurRadius; - appearance.borderWidth = aTheme.borderWidth; - appearance.arrowBase = aTheme.arrowBase; - appearance.arrowHeight = aTheme.arrowHeight; - appearance.outerShadowColor = aTheme.outerShadowColor; - appearance.outerShadowBlurRadius = aTheme.outerShadowBlurRadius; - appearance.outerShadowOffset = aTheme.outerShadowOffset; - appearance.outerCornerRadius = aTheme.outerCornerRadius; - appearance.minOuterCornerRadius = aTheme.minOuterCornerRadius; - appearance.innerShadowColor = aTheme.innerShadowColor; - appearance.innerShadowBlurRadius = aTheme.innerShadowBlurRadius; - appearance.innerShadowOffset = aTheme.innerShadowOffset; - appearance.innerCornerRadius = aTheme.innerCornerRadius; - appearance.viewContentInsets = aTheme.viewContentInsets; - appearance.overlayColor = aTheme.overlayColor; - appearance.preferredAlpha = aTheme.preferredAlpha; - } -} - -+ (WYPopoverTheme *)defaultTheme { - return defaultTheme_; -} - -+ (void)load { - [WYPopoverController setDefaultTheme:[WYPopoverTheme theme]]; -} - -- (id)init { - self = [super init]; - - if (self) { - // ignore orientation in iOS8 - _ignoreOrientation = (compileUsingIOS8SDK() && [[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]); - _popoverLayoutMargins = UIEdgeInsetsMake(10, 10, 10, 10); - _animationDuration = WY_POPOVER_DEFAULT_ANIMATION_DURATION; - - themeUpdatesEnabled = NO; - - [self setTheme:[WYPopoverController defaultTheme]]; - - themeIsUpdating = YES; - - WYPopoverBackgroundView *appearance = [WYPopoverBackgroundView appearance]; - _theme.usesRoundedArrow = appearance.usesRoundedArrow; - _theme.dimsBackgroundViewsTintColor = appearance.dimsBackgroundViewsTintColor; - _theme.tintColor = appearance.tintColor; - _theme.outerStrokeColor = appearance.outerStrokeColor; - _theme.innerStrokeColor = appearance.innerStrokeColor; - _theme.fillTopColor = appearance.fillTopColor; - _theme.fillBottomColor = appearance.fillBottomColor; - _theme.glossShadowColor = appearance.glossShadowColor; - _theme.glossShadowOffset = appearance.glossShadowOffset; - _theme.glossShadowBlurRadius = appearance.glossShadowBlurRadius; - _theme.borderWidth = appearance.borderWidth; - _theme.arrowBase = appearance.arrowBase; - _theme.arrowHeight = appearance.arrowHeight; - _theme.outerShadowColor = appearance.outerShadowColor; - _theme.outerShadowBlurRadius = appearance.outerShadowBlurRadius; - _theme.outerShadowOffset = appearance.outerShadowOffset; - _theme.outerCornerRadius = appearance.outerCornerRadius; - _theme.minOuterCornerRadius = appearance.minOuterCornerRadius; - _theme.innerShadowColor = appearance.innerShadowColor; - _theme.innerShadowBlurRadius = appearance.innerShadowBlurRadius; - _theme.innerShadowOffset = appearance.innerShadowOffset; - _theme.innerCornerRadius = appearance.innerCornerRadius; - _theme.viewContentInsets = appearance.viewContentInsets; - _theme.overlayColor = appearance.overlayColor; - _theme.preferredAlpha = appearance.preferredAlpha; - - - themeIsUpdating = NO; - themeUpdatesEnabled = YES; - - popoverContentSize_ = CGSizeZero; - } - - return self; -} - -- (id)initWithContentViewController:(UIViewController *)aViewController { - self = [self init]; - - if (self) { - _viewController = aViewController; - } - - return self; -} - -- (void)setTheme:(WYPopoverTheme *)value { - [self unregisterTheme]; - _theme = value; - [self registerTheme]; - [self updateThemeUI]; - - themeIsUpdating = NO; -} - -- (void)registerTheme { - if (_theme == nil) return; - - NSArray *keypaths = [_theme observableKeypaths]; - for (NSString *keypath in keypaths) { - [_theme addObserver:self forKeyPath:keypath options:NSKeyValueObservingOptionNew context:NULL]; - } -} - -- (void)unregisterTheme { - if (_theme == nil) return; - - @try { - NSArray *keypaths = [_theme observableKeypaths]; - for (NSString *keypath in keypaths) { - [_theme removeObserver:self forKeyPath:keypath]; - } - } - @catch (NSException * __unused exception) {} -} - -- (void)updateThemeUI { - if (_theme == nil || themeUpdatesEnabled == NO || themeIsUpdating == YES) return; - - if (_backgroundView != nil) { - _backgroundView.usesRoundedArrow = _theme.usesRoundedArrow; - _backgroundView.dimsBackgroundViewsTintColor = _theme.dimsBackgroundViewsTintColor; - _backgroundView.tintColor = _theme.tintColor; - _backgroundView.outerStrokeColor = _theme.outerStrokeColor; - _backgroundView.innerStrokeColor = _theme.innerStrokeColor; - _backgroundView.fillTopColor = _theme.fillTopColor; - _backgroundView.fillBottomColor = _theme.fillBottomColor; - _backgroundView.glossShadowColor = _theme.glossShadowColor; - _backgroundView.glossShadowOffset = _theme.glossShadowOffset; - _backgroundView.glossShadowBlurRadius = _theme.glossShadowBlurRadius; - _backgroundView.borderWidth = _theme.borderWidth; - _backgroundView.arrowBase = _theme.arrowBase; - _backgroundView.arrowHeight = _theme.arrowHeight; - _backgroundView.outerShadowColor = _theme.outerShadowColor; - _backgroundView.outerShadowBlurRadius = _theme.outerShadowBlurRadius; - _backgroundView.outerShadowOffset = _theme.outerShadowOffset; - _backgroundView.outerCornerRadius = _theme.outerCornerRadius; - _backgroundView.minOuterCornerRadius = _theme.minOuterCornerRadius; - _backgroundView.innerShadowColor = _theme.innerShadowColor; - _backgroundView.innerShadowBlurRadius = _theme.innerShadowBlurRadius; - _backgroundView.innerShadowOffset = _theme.innerShadowOffset; - _backgroundView.innerCornerRadius = _theme.innerCornerRadius; - _backgroundView.viewContentInsets = _theme.viewContentInsets; - _backgroundView.preferredAlpha = _theme.preferredAlpha; - [_backgroundView setNeedsDisplay]; - } - - if (_overlayView != nil) { - _overlayView.backgroundColor = _theme.overlayColor; - } - - [self positionPopover:NO]; - - [self setPopoverNavigationBarBackgroundImage]; -} - -- (void)beginThemeUpdates { - themeIsUpdating = YES; -} - -- (void)endThemeUpdates { - themeIsUpdating = NO; - [self updateThemeUI]; -} - -- (BOOL)isPopoverVisible { - BOOL result = (_overlayView != nil); - return result; -} - -- (UIViewController *)contentViewController { - return _viewController; -} - -- (CGSize)topViewControllerContentSize { - CGSize result = CGSizeZero; - - UIViewController *topViewController = _viewController; - - if ([_viewController isKindOfClass:[UINavigationController class]] == YES) { - UINavigationController *navigationController = (UINavigationController *)_viewController; - topViewController = [navigationController topViewController]; - } - -#ifdef WY_BASE_SDK_7_ENABLED - if ([topViewController respondsToSelector:@selector(preferredContentSize)]) { - result = topViewController.preferredContentSize; - } -#endif - - if (CGSizeEqualToSize(result, CGSizeZero)) { -#pragma clang diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" - result = topViewController.contentSizeForViewInPopover; -#pragma clang diagnostic pop - } - - if (CGSizeEqualToSize(result, CGSizeZero)) { - CGSize windowSize = [[UIApplication sharedApplication] keyWindow].bounds.size; - - UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; - - result = CGSizeMake(UIInterfaceOrientationIsPortrait(orientation) ? windowSize.width : windowSize.height, UIInterfaceOrientationIsLandscape(orientation) ? windowSize.width : windowSize.height); - } - - return result; -} - -- (CGSize)popoverContentSize { - CGSize result = popoverContentSize_; - if (CGSizeEqualToSize(result, CGSizeZero)) { - result = [self topViewControllerContentSize]; - } - return result; -} - -- (void)setPopoverContentSize:(CGSize)size { - popoverContentSize_ = size; - [self positionPopover:YES]; -} - -- (void)setPopoverContentSize:(CGSize)size animated:(BOOL)animated { - popoverContentSize_ = size; - [self positionPopover:animated]; -} - -- (void)performWithoutAnimation:(void (^)(void))aBlock { - if (aBlock) { - self.implicitAnimationsDisabled = YES; - aBlock(); - self.implicitAnimationsDisabled = NO; - } -} - -- (void)presentPopoverFromRect:(CGRect)aRect - inView:(UIView *)aView - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections - animated:(BOOL)aAnimated { - [self presentPopoverFromRect:aRect - inView:aView - permittedArrowDirections:aArrowDirections - animated:aAnimated - completion:nil]; -} - -- (void)presentPopoverFromRect:(CGRect)aRect - inView:(UIView *)aView - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections - animated:(BOOL)aAnimated - completion:(void (^)(void))completion { - [self presentPopoverFromRect:aRect - inView:aView - permittedArrowDirections:aArrowDirections - animated:aAnimated - options:WYPopoverAnimationOptionFade - completion:completion]; -} - -- (void)presentPopoverFromRect:(CGRect)aRect - inView:(UIView *)aView - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections - animated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aOptions { - [self presentPopoverFromRect:aRect - inView:aView - permittedArrowDirections:aArrowDirections - animated:aAnimated - options:aOptions - completion:nil]; -} - -- (void)presentPopoverFromRect:(CGRect)aRect - inView:(UIView *)aView - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections - animated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aOptions - completion:(void (^)(void))completion { - NSAssert((aArrowDirections != WYPopoverArrowDirectionUnknown), @"WYPopoverArrowDirection must not be UNKNOWN"); - - _rect = aRect; - _inView = aView; - _permittedArrowDirections = aArrowDirections; - _animated = aAnimated; - options = aOptions; - - if (!_inView) { - _inView = [UIApplication sharedApplication].keyWindow.rootViewController.view; - if (CGRectIsEmpty(_rect)) { - _rect = CGRectMake((int)_inView.bounds.size.width / 2 - 5, (int)_inView.bounds.size.height / 2 - 5, 10, 10); - } - } - - CGSize contentViewSize = self.popoverContentSize; - - if (_overlayView == nil) { - _overlayView = [[WYPopoverOverlayView alloc] initWithFrame:_inView.window.bounds]; - _overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _overlayView.autoresizesSubviews = NO; - _overlayView.delegate = self; - _overlayView.passthroughViews = _passthroughViews; - - _backgroundView = [[WYPopoverBackgroundView alloc] initWithContentSize:contentViewSize]; - _backgroundView.appearing = YES; - - _backgroundView.delegate = self; - _backgroundView.hidden = YES; - - UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:_backgroundView action:@selector(tapOut)]; - tap.cancelsTouchesInView = NO; - [_overlayView addGestureRecognizer:tap]; - - if (self.dismissOnTap) { - tap = [[UITapGestureRecognizer alloc] initWithTarget:_backgroundView action:@selector(tapOut)]; - tap.cancelsTouchesInView = NO; - [_backgroundView addGestureRecognizer:tap]; - } - - [_inView.window addSubview:_backgroundView]; - [_inView.window insertSubview:_overlayView belowSubview:_backgroundView]; - } - - [self updateThemeUI]; - - __weak __typeof__(self) weakSelf = self; - - void (^completionBlock)(BOOL) = ^(BOOL animated) { - - __typeof__(self) strongSelf = weakSelf; - - if (strongSelf) { - if (_isObserverAdded == NO) { - _isObserverAdded = YES; - - if ([strongSelf->_viewController respondsToSelector:@selector(preferredContentSize)]) { - [strongSelf->_viewController addObserver:self forKeyPath:NSStringFromSelector(@selector(preferredContentSize)) options:0 context:nil]; - } else { - [strongSelf->_viewController addObserver:self forKeyPath:NSStringFromSelector(@selector(contentSizeForViewInPopover)) options:0 context:nil]; - } - } - strongSelf->_backgroundView.appearing = NO; - } - - if (completion) { - completion(); - } else if (strongSelf && strongSelf->_delegate && [strongSelf->_delegate respondsToSelector:@selector(popoverControllerDidPresentPopover:)]) { - [strongSelf->_delegate popoverControllerDidPresentPopover:strongSelf]; - } - }; - - void (^adjustTintDimmed)() = ^() { -#ifdef WY_BASE_SDK_7_ENABLED - if (_backgroundView.dimsBackgroundViewsTintColor && [_inView.window respondsToSelector:@selector(setTintAdjustmentMode:)]) { - for (UIView *subview in _inView.window.subviews) { - if (subview != _backgroundView) { - [subview setTintAdjustmentMode:UIViewTintAdjustmentModeDimmed]; - } - } - } -#endif - }; - - _backgroundView.hidden = NO; - - if (_animated) { - if ((options & WYPopoverAnimationOptionFade) == WYPopoverAnimationOptionFade) { - _overlayView.alpha = 0; - _backgroundView.alpha = 0; - } - - CGAffineTransform endTransform = _backgroundView.transform; - - if ((options & WYPopoverAnimationOptionScale) == WYPopoverAnimationOptionScale) { - CGAffineTransform startTransform = [self transformForArrowDirection:_backgroundView.arrowDirection]; - _backgroundView.transform = startTransform; - } - - [UIView animateWithDuration:_animationDuration animations:^{ - __typeof__(self) strongSelf = weakSelf; - - if (strongSelf) { - strongSelf->_overlayView.alpha = 1; - strongSelf->_backgroundView.alpha = strongSelf->_backgroundView.preferredAlpha; - strongSelf->_backgroundView.transform = endTransform; - } - adjustTintDimmed(); - } completion:^(BOOL finished) { - completionBlock(YES); - }]; - } else { - adjustTintDimmed(); - completionBlock(NO); - } - - if (_isListeningNotifications == NO) { - _isListeningNotifications = YES; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(didChangeStatusBarOrientation:) - name:UIApplicationDidChangeStatusBarOrientationNotification - object:nil]; - - [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(didChangeDeviceOrientation:) - name:UIDeviceOrientationDidChangeNotification - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(keyboardWillShow:) - name:UIKeyboardWillShowNotification object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(keyboardWillHide:) - name:UIKeyboardWillHideNotification object:nil]; - } -} - -- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)aItem - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections - animated:(BOOL)aAnimated { - [self presentPopoverFromBarButtonItem:aItem - permittedArrowDirections:aArrowDirections - animated:aAnimated - completion:nil]; -} - -- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)aItem - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections - animated:(BOOL)aAnimated - completion:(void (^)(void))completion { - [self presentPopoverFromBarButtonItem:aItem - permittedArrowDirections:aArrowDirections - animated:aAnimated - options:WYPopoverAnimationOptionFade - completion:completion]; -} - -- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)aItem - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections - animated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aOptions { - [self presentPopoverFromBarButtonItem:aItem - permittedArrowDirections:aArrowDirections - animated:aAnimated - options:aOptions - completion:nil]; -} - -- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)aItem - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections - animated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aOptions - completion:(void (^)(void))completion { - _barButtonItem = aItem; - UIView *itemView = [_barButtonItem valueForKey:@"view"]; - aArrowDirections = WYPopoverArrowDirectionDown | WYPopoverArrowDirectionUp; - [self presentPopoverFromRect:itemView.bounds - inView:itemView - permittedArrowDirections:aArrowDirections - animated:aAnimated - options:aOptions - completion:completion]; -} - -- (void)presentPopoverAsDialogAnimated:(BOOL)aAnimated { - [self presentPopoverAsDialogAnimated:aAnimated - completion:nil]; -} - -- (void)presentPopoverAsDialogAnimated:(BOOL)aAnimated - completion:(void (^)(void))completion { - [self presentPopoverAsDialogAnimated:aAnimated - options:WYPopoverAnimationOptionFade - completion:completion]; -} - -- (void)presentPopoverAsDialogAnimated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aOptions { - [self presentPopoverAsDialogAnimated:aAnimated - options:aOptions - completion:nil]; -} - -- (void)presentPopoverAsDialogAnimated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aOptions - completion:(void (^)(void))completion { - [self presentPopoverFromRect:CGRectZero - inView:nil - permittedArrowDirections:WYPopoverArrowDirectionNone - animated:aAnimated - options:aOptions - completion:completion]; -} - -- (CGAffineTransform)transformForArrowDirection:(WYPopoverArrowDirection)arrowDirection { - CGAffineTransform transform = _backgroundView.transform; - - UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; - - CGSize containerViewSize = _backgroundView.frame.size; - - if (_backgroundView.arrowHeight > 0) { - if (UIInterfaceOrientationIsLandscape(orientation)) { - containerViewSize.width = _backgroundView.frame.size.height; - containerViewSize.height = _backgroundView.frame.size.width; - } - - //WY_LOG(@"containerView.arrowOffset = %f", containerView.arrowOffset); - //WY_LOG(@"containerViewSize = %@", NSStringFromCGSize(containerViewSize)); - //WY_LOG(@"orientation = %@", WYStringFromOrientation(orientation)); - - if (arrowDirection == WYPopoverArrowDirectionDown) { - transform = CGAffineTransformTranslate(transform, _backgroundView.arrowOffset, containerViewSize.height / 2); - } - - if (arrowDirection == WYPopoverArrowDirectionUp) { - transform = CGAffineTransformTranslate(transform, _backgroundView.arrowOffset, -containerViewSize.height / 2); - } - - if (arrowDirection == WYPopoverArrowDirectionRight) { - transform = CGAffineTransformTranslate(transform, containerViewSize.width / 2, _backgroundView.arrowOffset); - } - - if (arrowDirection == WYPopoverArrowDirectionLeft) { - transform = CGAffineTransformTranslate(transform, -containerViewSize.width / 2, _backgroundView.arrowOffset); - } - } - - transform = CGAffineTransformScale(transform, 0.01, 0.01); - - return transform; -} - -- (void)setPopoverNavigationBarBackgroundImage { - if ([_viewController isKindOfClass:[UINavigationController class]] == YES) { - UINavigationController *navigationController = (UINavigationController *)_viewController; - navigationController.wy_embedInPopover = YES; - -#ifdef WY_BASE_SDK_7_ENABLED - if ([navigationController respondsToSelector:@selector(setEdgesForExtendedLayout:)]) { - UIViewController *topViewController = [navigationController topViewController]; - [topViewController setEdgesForExtendedLayout:UIRectEdgeNone]; - } -#endif - - if (_wantsDefaultContentAppearance == NO) { - [navigationController.navigationBar setBackgroundImage:[UIImage wy_imageWithColor:[UIColor clearColor]] forBarMetrics:UIBarMetricsDefault]; - } - } - - _viewController.view.clipsToBounds = YES; - - if (_backgroundView.borderWidth == 0) { - _viewController.view.layer.cornerRadius = _backgroundView.outerCornerRadius; - } -} - -- (void)positionPopover:(BOOL)aAnimated { - CGRect savedContainerFrame = _backgroundView.frame; - UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; - CGSize contentViewSize = self.popoverContentSize; - CGSize minContainerSize = WY_POPOVER_MIN_SIZE; - - CGRect viewFrame; - CGRect containerFrame = CGRectZero; - float minX, maxX, minY, maxY, offset = 0; - CGSize containerViewSize = CGSizeZero; - - float overlayWidth; - float overlayHeight; - - float keyboardHeight; - - if (_ignoreOrientation) { - overlayWidth = _overlayView.window.frame.size.width; - overlayHeight = _overlayView.window.frame.size.height; - - CGRect convertedFrame = [_overlayView.window convertRect:WYKeyboardListener.rect toView:_overlayView]; - keyboardHeight = convertedFrame.size.height; - } else { - overlayWidth = UIInterfaceOrientationIsPortrait(orientation) ? _overlayView.bounds.size.width : _overlayView.bounds.size.height; - overlayHeight = UIInterfaceOrientationIsPortrait(orientation) ? _overlayView.bounds.size.height : _overlayView.bounds.size.width; - - keyboardHeight = UIInterfaceOrientationIsPortrait(orientation) ? WYKeyboardListener.rect.size.height : WYKeyboardListener.rect.size.width; - } - - if (_delegate && [_delegate respondsToSelector:@selector(popoverControllerShouldIgnoreKeyboardBounds:)]) { - BOOL shouldIgnore = [_delegate popoverControllerShouldIgnoreKeyboardBounds:self]; - - if (shouldIgnore) { - keyboardHeight = 0; - } - } - - WYPopoverArrowDirection arrowDirection = _permittedArrowDirections; - - _overlayView.bounds = _inView.window.bounds; - _backgroundView.transform = CGAffineTransformIdentity; - - viewFrame = [_inView convertRect:_rect toView:nil]; - - viewFrame = WYRectInWindowBounds(viewFrame, orientation); - - minX = _popoverLayoutMargins.left; - maxX = overlayWidth - _popoverLayoutMargins.right; - minY = WYStatusBarHeight() + _popoverLayoutMargins.top; - maxY = overlayHeight - _popoverLayoutMargins.bottom - keyboardHeight; - - // Which direction ? - // - arrowDirection = [self arrowDirectionForRect:_rect - inView:_inView - contentSize:contentViewSize - arrowHeight:_backgroundView.arrowHeight - permittedArrowDirections:arrowDirection]; - - // Position of the popover - // - - minX -= _backgroundView.outerShadowInsets.left; - maxX += _backgroundView.outerShadowInsets.right; - minY -= _backgroundView.outerShadowInsets.top; - maxY += _backgroundView.outerShadowInsets.bottom; - - if (arrowDirection == WYPopoverArrowDirectionDown) { - _backgroundView.arrowDirection = WYPopoverArrowDirectionDown; - containerViewSize = [_backgroundView sizeThatFits:contentViewSize]; - - containerFrame = CGRectZero; - containerFrame.size = containerViewSize; - containerFrame.size.width = MIN(maxX - minX, containerFrame.size.width); - containerFrame.size.height = MIN(maxY - minY, containerFrame.size.height); - - _backgroundView.frame = CGRectIntegral(containerFrame); - - _backgroundView.center = CGPointMake(viewFrame.origin.x + viewFrame.size.width / 2, viewFrame.origin.y + viewFrame.size.height / 2); - - containerFrame = _backgroundView.frame; - - offset = 0; - - if (containerFrame.origin.x < minX) { - offset = minX - containerFrame.origin.x; - containerFrame.origin.x = minX; - offset = -offset; - } else if (containerFrame.origin.x + containerFrame.size.width > maxX) { - offset = (_backgroundView.frame.origin.x + _backgroundView.frame.size.width) - maxX; - containerFrame.origin.x -= offset; - } - - _backgroundView.arrowOffset = offset; - offset = _backgroundView.frame.size.height / 2 + viewFrame.size.height / 2 - _backgroundView.outerShadowInsets.bottom; - - containerFrame.origin.y -= offset; - - if (containerFrame.origin.y < minY) { - offset = minY - containerFrame.origin.y; - containerFrame.size.height -= offset; - - if (containerFrame.size.height < minContainerSize.height) { - // popover is overflowing - offset -= (minContainerSize.height - containerFrame.size.height); - containerFrame.size.height = minContainerSize.height; - } - - containerFrame.origin.y += offset; - } - } - - if (arrowDirection == WYPopoverArrowDirectionUp) { - _backgroundView.arrowDirection = WYPopoverArrowDirectionUp; - containerViewSize = [_backgroundView sizeThatFits:contentViewSize]; - - containerFrame = CGRectZero; - containerFrame.size = containerViewSize; - containerFrame.size.width = MIN(maxX - minX, containerFrame.size.width); - containerFrame.size.height = MIN(maxY - minY, containerFrame.size.height); - - _backgroundView.frame = containerFrame; - - _backgroundView.center = CGPointMake(viewFrame.origin.x + viewFrame.size.width / 2, viewFrame.origin.y + viewFrame.size.height / 2); - - containerFrame = _backgroundView.frame; - - offset = 0; - - if (containerFrame.origin.x < minX) { - offset = minX - containerFrame.origin.x; - containerFrame.origin.x = minX; - offset = -offset; - } - else if (containerFrame.origin.x + containerFrame.size.width > maxX) { - offset = (_backgroundView.frame.origin.x + _backgroundView.frame.size.width) - maxX; - containerFrame.origin.x -= offset; - } - - _backgroundView.arrowOffset = offset; - offset = _backgroundView.frame.size.height / 2 + viewFrame.size.height / 2 - _backgroundView.outerShadowInsets.top; - - containerFrame.origin.y += offset; - - if (containerFrame.origin.y + containerFrame.size.height > maxY) { - offset = (containerFrame.origin.y + containerFrame.size.height) - maxY; - containerFrame.size.height -= offset; - - if (containerFrame.size.height < minContainerSize.height) { - // popover is overflowing - containerFrame.size.height = minContainerSize.height; - } - } - } - - if (arrowDirection == WYPopoverArrowDirectionRight) { - _backgroundView.arrowDirection = WYPopoverArrowDirectionRight; - containerViewSize = [_backgroundView sizeThatFits:contentViewSize]; - - containerFrame = CGRectZero; - containerFrame.size = containerViewSize; - containerFrame.size.width = MIN(maxX - minX, containerFrame.size.width); - containerFrame.size.height = MIN(maxY - minY, containerFrame.size.height); - - _backgroundView.frame = CGRectIntegral(containerFrame); - - _backgroundView.center = CGPointMake(viewFrame.origin.x + viewFrame.size.width / 2, viewFrame.origin.y + viewFrame.size.height / 2); - - containerFrame = _backgroundView.frame; - - offset = _backgroundView.frame.size.width / 2 + viewFrame.size.width / 2 - _backgroundView.outerShadowInsets.right; - - containerFrame.origin.x -= offset; - - if (containerFrame.origin.x < minX) { - offset = minX - containerFrame.origin.x; - containerFrame.size.width -= offset; - - if (containerFrame.size.width < minContainerSize.width) { - // popover is overflowing - offset -= (minContainerSize.width - containerFrame.size.width); - containerFrame.size.width = minContainerSize.width; - } - - containerFrame.origin.x += offset; - } - - offset = 0; - - if (containerFrame.origin.y < minY) { - offset = minY - containerFrame.origin.y; - containerFrame.origin.y = minY; - offset = -offset; - } else if (containerFrame.origin.y + containerFrame.size.height > maxY) { - offset = (_backgroundView.frame.origin.y + _backgroundView.frame.size.height) - maxY; - containerFrame.origin.y -= offset; - } - - _backgroundView.arrowOffset = offset; - } - - if (arrowDirection == WYPopoverArrowDirectionLeft) { - _backgroundView.arrowDirection = WYPopoverArrowDirectionLeft; - containerViewSize = [_backgroundView sizeThatFits:contentViewSize]; - - containerFrame = CGRectZero; - containerFrame.size = containerViewSize; - containerFrame.size.width = MIN(maxX - minX, containerFrame.size.width); - containerFrame.size.height = MIN(maxY - minY, containerFrame.size.height); - _backgroundView.frame = containerFrame; - - _backgroundView.center = CGPointMake(viewFrame.origin.x + viewFrame.size.width / 2, viewFrame.origin.y + viewFrame.size.height / 2); - - containerFrame = CGRectIntegral(_backgroundView.frame); - - offset = _backgroundView.frame.size.width / 2 + viewFrame.size.width / 2 - _backgroundView.outerShadowInsets.left; - - containerFrame.origin.x += offset; - - if (containerFrame.origin.x + containerFrame.size.width > maxX) { - offset = (containerFrame.origin.x + containerFrame.size.width) - maxX; - containerFrame.size.width -= offset; - - if (containerFrame.size.width < minContainerSize.width) { - // popover is overflowing - containerFrame.size.width = minContainerSize.width; - } - } - - offset = 0; - - if (containerFrame.origin.y < minY) { - offset = minY - containerFrame.origin.y; - containerFrame.origin.y = minY; - offset = -offset; - } else if (containerFrame.origin.y + containerFrame.size.height > maxY) { - offset = (_backgroundView.frame.origin.y + _backgroundView.frame.size.height) - maxY; - containerFrame.origin.y -= offset; - } - - _backgroundView.arrowOffset = offset; - } - - if (arrowDirection == WYPopoverArrowDirectionNone) { - _backgroundView.arrowDirection = WYPopoverArrowDirectionNone; - containerViewSize = [_backgroundView sizeThatFits:contentViewSize]; - - containerFrame = CGRectZero; - containerFrame.size = containerViewSize; - containerFrame.size.width = MIN(maxX - minX, containerFrame.size.width); - containerFrame.size.height = MIN(maxY - minY, containerFrame.size.height); - _backgroundView.frame = CGRectIntegral(containerFrame); - - _backgroundView.center = CGPointMake(minX + (maxX - minX) / 2, minY + (maxY - minY) / 2); - - containerFrame = _backgroundView.frame; - - _backgroundView.arrowOffset = offset; - } - - containerFrame = CGRectIntegral(containerFrame); - - _backgroundView.frame = containerFrame; - - _backgroundView.wantsDefaultContentAppearance = _wantsDefaultContentAppearance; - - [_backgroundView setViewController:_viewController]; - - // keyboard support - if (keyboardHeight > 0) { - - float keyboardY = UIInterfaceOrientationIsPortrait(orientation) ? WYKeyboardListener.rect.origin.y : WYKeyboardListener.rect.origin.x; - - float yOffset = containerFrame.origin.y + containerFrame.size.height - keyboardY; - - if (yOffset > 0) { - - if (containerFrame.origin.y - yOffset < minY) { - yOffset -= minY - (containerFrame.origin.y - yOffset); - } - - if ([_delegate respondsToSelector:@selector(popoverController:willTranslatePopoverWithYOffset:)]) { - [_delegate popoverController:self willTranslatePopoverWithYOffset:&yOffset]; - } - - containerFrame.origin.y -= yOffset; - } - } - - CGPoint containerOrigin = containerFrame.origin; - - _backgroundView.transform = CGAffineTransformMakeRotation(WYInterfaceOrientationAngleOfOrientation(orientation)); - - containerFrame = _backgroundView.frame; - - containerFrame.origin = WYPointRelativeToOrientation(containerOrigin, containerFrame.size, orientation); - - if (aAnimated == YES && !self.implicitAnimationsDisabled) { - _backgroundView.frame = savedContainerFrame; - __weak __typeof__(self) weakSelf = self; - [UIView animateWithDuration:0.10f animations:^{ - __typeof__(self) strongSelf = weakSelf; - strongSelf->_backgroundView.frame = containerFrame; - }]; - } else { - _backgroundView.frame = containerFrame; - } - - [_backgroundView setNeedsDisplay]; - -// WY_LOG(@"popoverContainerView.frame = %@", NSStringFromCGRect(_backgroundView.frame)); -} - -- (void)dismissPopoverAnimated:(BOOL)aAnimated { - [self dismissPopoverAnimated:aAnimated - options:options - completion:nil]; -} - -- (void)dismissPopoverAnimated:(BOOL)aAnimated - completion:(void (^)(void))completion { - [self dismissPopoverAnimated:aAnimated - options:options - completion:completion]; -} - -- (void)dismissPopoverAnimated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aOptions { - [self dismissPopoverAnimated:aAnimated - options:aOptions - completion:nil]; -} - -- (void)dismissPopoverAnimated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aOptions - completion:(void (^)(void))completion { - [self dismissPopoverAnimated:aAnimated - options:aOptions - completion:completion - callDelegate:NO]; -} - -- (void)dismissPopoverAnimated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aOptions - completion:(void (^)(void))completion - callDelegate:(BOOL)callDelegate { - float duration = self.animationDuration; - WYPopoverAnimationOptions style = aOptions; - - __weak __typeof__(self) weakSelf = self; - - - void (^adjustTintAutomatic)() = ^() { -#ifdef WY_BASE_SDK_7_ENABLED - if ([_inView.window respondsToSelector:@selector(setTintAdjustmentMode:)]) { - for (UIView *subview in _inView.window.subviews) { - if (subview != _backgroundView) { - [subview setTintAdjustmentMode:UIViewTintAdjustmentModeAutomatic]; - } - } - } -#endif - }; - - void (^completionBlock)() = ^() { - __typeof__(self) strongSelf = weakSelf; - - if (strongSelf) { - [strongSelf->_backgroundView removeFromSuperview]; - - strongSelf->_backgroundView = nil; - - [strongSelf->_overlayView removeFromSuperview]; - strongSelf->_overlayView = nil; - - // inView is captured strongly in presentPopoverInRect:... method, so it needs to be released in dismiss method to avoid potential retain cycles - strongSelf->_inView = nil; - } - - if (completion) { - completion(); - } - else if (callDelegate && strongSelf && strongSelf->_delegate && [strongSelf->_delegate respondsToSelector:@selector(popoverControllerDidDismissPopover:)]) { - [strongSelf->_delegate popoverControllerDidDismissPopover:strongSelf]; - } - - if (self.dismissCompletionBlock) { - self.dismissCompletionBlock(strongSelf); - } - }; - - if (_isListeningNotifications == YES) { - _isListeningNotifications = NO; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIApplicationDidChangeStatusBarOrientationNotification - object:nil]; - - [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIDeviceOrientationDidChangeNotification - object:nil]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIKeyboardWillShowNotification - object:nil]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIKeyboardWillHideNotification - object:nil]; - } - - @try { - if (_isObserverAdded == YES) { - _isObserverAdded = NO; - - if ([_viewController respondsToSelector:@selector(preferredContentSize)]) { - [_viewController removeObserver:self forKeyPath:NSStringFromSelector(@selector(preferredContentSize))]; - } else { - [_viewController removeObserver:self forKeyPath:NSStringFromSelector(@selector(contentSizeForViewInPopover))]; - } - } - } - @catch (NSException * __unused exception) {} - - if (aAnimated && !self.implicitAnimationsDisabled) { - [UIView animateWithDuration:duration animations:^{ - __typeof__(self) strongSelf = weakSelf; - if (strongSelf) { - if ((style & WYPopoverAnimationOptionFade) == WYPopoverAnimationOptionFade) { - strongSelf->_backgroundView.alpha = 0; - } - - if ((style & WYPopoverAnimationOptionScale) == WYPopoverAnimationOptionScale) { - CGAffineTransform endTransform = [self transformForArrowDirection:strongSelf->_backgroundView.arrowDirection]; - strongSelf->_backgroundView.transform = endTransform; - } - strongSelf->_overlayView.alpha = 0; - } - adjustTintAutomatic(); - } completion:^(BOOL finished) { - completionBlock(); - }]; - } else { - adjustTintAutomatic(); - completionBlock(); - } -} - -#pragma mark KVO - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if (object == _viewController) { - if ([keyPath isEqualToString:NSStringFromSelector(@selector(preferredContentSize))] - || [keyPath isEqualToString:NSStringFromSelector(@selector(contentSizeForViewInPopover))]) { - CGSize contentSize = [self topViewControllerContentSize]; - [self setPopoverContentSize:contentSize]; - } - } else if (object == _theme) { - [self updateThemeUI]; - } -} - -#pragma mark WYPopoverOverlayViewDelegate - -- (void)popoverOverlayViewDidTouch:(WYPopoverOverlayView *)aOverlayView { - BOOL shouldDismiss = !_viewController.modalInPopover; - - if (shouldDismiss && _delegate && [_delegate respondsToSelector:@selector(popoverControllerShouldDismissPopover:)]) { - shouldDismiss = [_delegate popoverControllerShouldDismissPopover:self]; - } - - if (shouldDismiss) { - [self dismissPopoverAnimated:_animated options:options completion:nil callDelegate:YES]; - } -} - -#pragma mark WYPopoverBackgroundViewDelegate - -- (void)popoverBackgroundViewDidTouchOutside:(WYPopoverBackgroundView *)aBackgroundView { - [self popoverOverlayViewDidTouch:nil]; -} - -#pragma mark Private -- (WYPopoverArrowDirection)arrowDirectionForRect:(CGRect)aRect - inView:(UIView *)aView - contentSize:(CGSize)contentSize - arrowHeight:(float)arrowHeight - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections { - WYPopoverArrowDirection arrowDirection = WYPopoverArrowDirectionUnknown; - - NSMutableArray *areas = [NSMutableArray arrayWithCapacity:0]; - WYPopoverArea *area; - - if ((arrowDirections & WYPopoverArrowDirectionDown) == WYPopoverArrowDirectionDown) { - area = [[WYPopoverArea alloc] init]; - area.areaSize = [self sizeForRect:aRect inView:aView arrowHeight:arrowHeight arrowDirection:WYPopoverArrowDirectionDown]; - area.arrowDirection = WYPopoverArrowDirectionDown; - [areas addObject:area]; - } - - if ((arrowDirections & WYPopoverArrowDirectionUp) == WYPopoverArrowDirectionUp) { - area = [[WYPopoverArea alloc] init]; - area.areaSize = [self sizeForRect:aRect inView:aView arrowHeight:arrowHeight arrowDirection:WYPopoverArrowDirectionUp]; - area.arrowDirection = WYPopoverArrowDirectionUp; - [areas addObject:area]; - } - - if ((arrowDirections & WYPopoverArrowDirectionLeft) == WYPopoverArrowDirectionLeft) { - area = [[WYPopoverArea alloc] init]; - area.areaSize = [self sizeForRect:aRect inView:aView arrowHeight:arrowHeight arrowDirection:WYPopoverArrowDirectionLeft]; - area.arrowDirection = WYPopoverArrowDirectionLeft; - [areas addObject:area]; - } - - if ((arrowDirections & WYPopoverArrowDirectionRight) == WYPopoverArrowDirectionRight) { - area = [[WYPopoverArea alloc] init]; - area.areaSize = [self sizeForRect:aRect inView:aView arrowHeight:arrowHeight arrowDirection:WYPopoverArrowDirectionRight]; - area.arrowDirection = WYPopoverArrowDirectionRight; - [areas addObject:area]; - } - - if ((arrowDirections & WYPopoverArrowDirectionNone) == WYPopoverArrowDirectionNone) { - area = [[WYPopoverArea alloc] init]; - area.areaSize = [self sizeForRect:aRect inView:aView arrowHeight:arrowHeight arrowDirection:WYPopoverArrowDirectionNone]; - area.arrowDirection = WYPopoverArrowDirectionNone; - [areas addObject:area]; - } - - if ([areas count] > 1) { - NSIndexSet* indexes = [areas indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { - WYPopoverArea* popoverArea = (WYPopoverArea*)obj; - - BOOL result = (popoverArea.areaSize.width > 0 && popoverArea.areaSize.height > 0); - - return result; - }]; - - areas = [NSMutableArray arrayWithArray:[areas objectsAtIndexes:indexes]]; - } - - [areas sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { - WYPopoverArea *area1 = (WYPopoverArea *)obj1; - WYPopoverArea *area2 = (WYPopoverArea *)obj2; - - float val1 = area1.value; - float val2 = area2.value; - - NSComparisonResult result = NSOrderedSame; - - if (val1 > val2) { - result = NSOrderedAscending; - } else if (val1 < val2) { - result = NSOrderedDescending; - } - - return result; - }]; - - for (NSUInteger i = 0; i < [areas count]; i++) { - WYPopoverArea *popoverArea = (WYPopoverArea *)[areas objectAtIndex:i]; - - if (popoverArea.areaSize.width >= contentSize.width) { - arrowDirection = popoverArea.arrowDirection; - break; - } - } - - if (arrowDirection == WYPopoverArrowDirectionUnknown) { - if ([areas count] > 0) { - arrowDirection = ((WYPopoverArea *)[areas objectAtIndex:0]).arrowDirection; - } else { - if ((arrowDirections & WYPopoverArrowDirectionDown) == WYPopoverArrowDirectionDown) { - arrowDirection = WYPopoverArrowDirectionDown; - } else if ((arrowDirections & WYPopoverArrowDirectionUp) == WYPopoverArrowDirectionUp) { - arrowDirection = WYPopoverArrowDirectionUp; - } else if ((arrowDirections & WYPopoverArrowDirectionLeft) == WYPopoverArrowDirectionLeft) { - arrowDirection = WYPopoverArrowDirectionLeft; - } else { - arrowDirection = WYPopoverArrowDirectionRight; - } - } - } - - return arrowDirection; -} - -- (CGSize)sizeForRect:(CGRect)aRect - inView:(UIView *)aView - arrowHeight:(float)arrowHeight - arrowDirection:(WYPopoverArrowDirection)arrowDirection { - UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; - - CGRect viewFrame = [aView convertRect:aRect toView:nil]; - viewFrame = WYRectInWindowBounds(viewFrame, orientation); - - float minX, maxX, minY, maxY = 0; - - float keyboardHeight = WYKeyboardListener.rect.size.height; - float overlayWidth = _overlayView.bounds.size.width; - float overlayHeight = _overlayView.bounds.size.height; - - if (!_ignoreOrientation && UIInterfaceOrientationIsLandscape(orientation)) { - keyboardHeight = WYKeyboardListener.rect.size.width; - overlayWidth = _overlayView.bounds.size.height; - overlayHeight = _overlayView.bounds.size.width; - } - - if (_delegate && [_delegate respondsToSelector:@selector(popoverControllerShouldIgnoreKeyboardBounds:)]) { - BOOL shouldIgnore = [_delegate popoverControllerShouldIgnoreKeyboardBounds:self]; - - if (shouldIgnore) { - keyboardHeight = 0; - } - } - - minX = _popoverLayoutMargins.left; - maxX = overlayWidth - _popoverLayoutMargins.right; - minY = WYStatusBarHeight() + _popoverLayoutMargins.top; - maxY = overlayHeight - _popoverLayoutMargins.bottom - keyboardHeight; - - CGSize result = CGSizeZero; - - if (arrowDirection == WYPopoverArrowDirectionLeft) { - result.width = maxX - (viewFrame.origin.x + viewFrame.size.width); - result.width -= arrowHeight; - result.height = maxY - minY; - } else if (arrowDirection == WYPopoverArrowDirectionRight) { - result.width = viewFrame.origin.x - minX; - result.width -= arrowHeight; - result.height = maxY - minY; - } else if (arrowDirection == WYPopoverArrowDirectionDown) { - result.width = maxX - minX; - result.height = viewFrame.origin.y - minY; - result.height -= arrowHeight; - } else if (arrowDirection == WYPopoverArrowDirectionUp) { - result.width = maxX - minX; - result.height = maxY - (viewFrame.origin.y + viewFrame.size.height); - result.height -= arrowHeight; - } else if (arrowDirection == WYPopoverArrowDirectionNone) { - result.width = maxX - minX; - result.height = maxY - minY; - } - - return result; -} - -#pragma mark Inline functions - -static BOOL compileUsingIOS8SDK() { - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 - return YES; -#endif - - return NO; -} - -__unused static NSString* WYStringFromOrientation(NSInteger orientation) { - NSString *result = @"Unknown"; - - switch (orientation) { - case UIInterfaceOrientationPortrait: - result = @"Portrait"; - break; - case UIInterfaceOrientationPortraitUpsideDown: - result = @"Portrait UpsideDown"; - break; - case UIInterfaceOrientationLandscapeLeft: - result = @"Landscape Left"; - break; - case UIInterfaceOrientationLandscapeRight: - result = @"Landscape Right"; - break; - default: - break; - } - - return result; -} - -static float WYStatusBarHeight() { - if (compileUsingIOS8SDK() && [[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) { - CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; - return statusBarFrame.size.height; - } else { - UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; - float statusBarHeight = 0; - CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; - statusBarHeight = statusBarFrame.size.height; - - if (UIInterfaceOrientationIsLandscape(orientation)) - { - statusBarHeight = statusBarFrame.size.width; - } - - return statusBarHeight; - } -} - -static float WYInterfaceOrientationAngleOfOrientation(UIInterfaceOrientation orientation) { - float angle; - // no transformation needed in iOS 8 - if (compileUsingIOS8SDK() && [[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) { - angle = 0.0; - } else { - switch (orientation) { - case UIInterfaceOrientationPortraitUpsideDown: - angle = M_PI; - break; - case UIInterfaceOrientationLandscapeLeft: - angle = -M_PI_2; - break; - case UIInterfaceOrientationLandscapeRight: - angle = M_PI_2; - break; - default: - angle = 0.0; - break; - } - } - return angle; -} - -static CGRect WYRectInWindowBounds(CGRect rect, UIInterfaceOrientation orientation) { - - UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; - - float windowWidth = keyWindow.bounds.size.width; - float windowHeight = keyWindow.bounds.size.height; - - CGRect result = rect; - if (!(compileUsingIOS8SDK() && [[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)])) { - - if (orientation == UIInterfaceOrientationLandscapeRight) { - - result.origin.x = rect.origin.y; - result.origin.y = windowWidth - rect.origin.x - rect.size.width; - result.size.width = rect.size.height; - result.size.height = rect.size.width; - } - - if (orientation == UIInterfaceOrientationLandscapeLeft) { - - result.origin.x = windowHeight - rect.origin.y - rect.size.height; - result.origin.y = rect.origin.x; - result.size.width = rect.size.height; - result.size.height = rect.size.width; - } - - if (orientation == UIInterfaceOrientationPortraitUpsideDown) { - - result.origin.x = windowWidth - rect.origin.x - rect.size.width; - result.origin.y = windowHeight - rect.origin.y - rect.size.height; - } - } - - return result; -} - -static CGPoint WYPointRelativeToOrientation(CGPoint origin, CGSize size, UIInterfaceOrientation orientation) { - - UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; - - float windowWidth = keyWindow.bounds.size.width; - float windowHeight = keyWindow.bounds.size.height; - - CGPoint result = origin; - if (!(compileUsingIOS8SDK() && [[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)])) { - - if (orientation == UIInterfaceOrientationLandscapeRight) { - result.x = windowWidth - origin.y - size.width; - result.y = origin.x; - } - - if (orientation == UIInterfaceOrientationLandscapeLeft) { - result.x = origin.y; - result.y = windowHeight - origin.x - size.height; - } - - if (orientation == UIInterfaceOrientationPortraitUpsideDown) { - result.x = windowWidth - origin.x - size.width; - result.y = windowHeight - origin.y - size.height; - } - } - - return result; -} - -#pragma mark Selectors - -- (void)didChangeStatusBarOrientation:(NSNotification *)notification { - _isInterfaceOrientationChanging = YES; -} - -- (void)didChangeDeviceOrientation:(NSNotification *)notification { - if (_isInterfaceOrientationChanging == NO) return; - - _isInterfaceOrientationChanging = NO; - - if ([_viewController isKindOfClass:[UINavigationController class]]) { - UINavigationController* navigationController = (UINavigationController*)_viewController; - - if (navigationController.navigationBarHidden == NO) { - navigationController.navigationBarHidden = YES; - navigationController.navigationBarHidden = NO; - } - } - - if (_barButtonItem) { - _inView = [_barButtonItem valueForKey:@"view"]; - _rect = _inView.bounds; - } else if ([_delegate respondsToSelector:@selector(popoverController:willRepositionPopoverToRect:inView:)]) { - CGRect anotherRect; - UIView *anotherInView; - - [_delegate popoverController:self willRepositionPopoverToRect:&anotherRect inView:&anotherInView]; - -#pragma clang diagnostic push -#pragma GCC diagnostic ignored "-Wtautological-pointer-compare" - if (&anotherRect != NULL) { - _rect = anotherRect; - } - - if (&anotherInView != NULL) { - _inView = anotherInView; - } -#pragma GCC diagnostic pop - } - - [self positionPopover:NO]; -} - -- (void)keyboardWillShow:(NSNotification *)notification { - //UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; - //WY_LOG(@"orientation = %@", WYStringFromOrientation(orientation)); - //WY_LOG(@"WYKeyboardListener.rect = %@", NSStringFromCGRect(WYKeyboardListener.rect)); - - BOOL shouldIgnore = NO; - - if (_delegate && [_delegate respondsToSelector:@selector(popoverControllerShouldIgnoreKeyboardBounds:)]) { - shouldIgnore = [_delegate popoverControllerShouldIgnoreKeyboardBounds:self]; - } - - if (shouldIgnore == NO) { - [self positionPopover:YES]; - } -} - -- (void)keyboardWillHide:(NSNotification *)notification { - BOOL shouldIgnore = NO; - - if (_delegate && [_delegate respondsToSelector:@selector(popoverControllerShouldIgnoreKeyboardBounds:)]) { - shouldIgnore = [_delegate popoverControllerShouldIgnoreKeyboardBounds:self]; - } - - if (shouldIgnore == NO) { - [self positionPopover:YES]; - } -} - -#pragma mark Memory management - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [_backgroundView removeFromSuperview]; - [_backgroundView setDelegate:nil]; - - [_overlayView removeFromSuperview]; - [_overlayView setDelegate:nil]; - @try { - if (_isObserverAdded == YES) { - _isObserverAdded = NO; - - if ([_viewController respondsToSelector:@selector(preferredContentSize)]) { - [_viewController removeObserver:self forKeyPath:NSStringFromSelector(@selector(preferredContentSize))]; - } else { - [_viewController removeObserver:self forKeyPath:NSStringFromSelector(@selector(contentSizeForViewInPopover))]; - } - } - } - @catch (NSException *exception) { - } - @finally { - _viewController = nil; - } - - [self unregisterTheme]; - - _barButtonItem = nil; - _passthroughViews = nil; - _inView = nil; - _overlayView = nil; - _backgroundView = nil; - - _theme = nil; -} - -@end diff --git a/clients/ios/Other Sources/WYPopoverController/WYStoryboardPopoverSegue.h b/clients/ios/Other Sources/WYPopoverController/WYStoryboardPopoverSegue.h deleted file mode 100755 index c070a0b32..000000000 --- a/clients/ios/Other Sources/WYPopoverController/WYStoryboardPopoverSegue.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Version 0.3.6 - - WYPopoverController is available under the MIT license. - - Copyright © 2013 Nicolas CHENG - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#import -#import "WYPopoverController.h" - -@interface WYStoryboardPopoverSegue : UIStoryboardSegue - -- (WYPopoverController*)popoverControllerWithSender:(id)sender - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections - animated:(BOOL)animated; - -- (WYPopoverController*)popoverControllerWithSender:(id)sender - permittedArrowDirections:(WYPopoverArrowDirection)arrowDirections - animated:(BOOL)animated - options:(WYPopoverAnimationOptions)options; - -@end \ No newline at end of file diff --git a/clients/ios/Other Sources/WYPopoverController/WYStoryboardPopoverSegue.m b/clients/ios/Other Sources/WYPopoverController/WYStoryboardPopoverSegue.m deleted file mode 100755 index 90ca735a6..000000000 --- a/clients/ios/Other Sources/WYPopoverController/WYStoryboardPopoverSegue.m +++ /dev/null @@ -1,97 +0,0 @@ -/* - Version 0.3.6 - - WYPopoverController is available under the MIT license. - - Copyright © 2013 Nicolas CHENG - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#import "WYStoryboardPopoverSegue.h" - - -//////////////////////////////////////////////////////////////////////////// - -@interface WYStoryboardPopoverSegue() -{ - WYPopoverController *_popoverController; - id _sender; - WYPopoverArrowDirection _arrowDirections; - WYPopoverAnimationOptions _options; - BOOL _animated; -} - -@end - -//////////////////////////////////////////////////////////////////////////// - -@implementation WYStoryboardPopoverSegue - -- (void)perform -{ - if ([_sender isKindOfClass:[UIBarButtonItem class]]) - { - [_popoverController presentPopoverFromBarButtonItem:(UIBarButtonItem*)_sender - permittedArrowDirections:_arrowDirections - animated:_animated - options:_options]; - } - else - { - UIView *view = (UIView *)_sender; - [_popoverController presentPopoverFromRect:view.bounds - inView:view - permittedArrowDirections:_arrowDirections - animated:_animated - options:_options]; - } -} - -- (WYPopoverController *)popoverControllerWithSender:(id)aSender - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections - animated:(BOOL)aAnimated -{ - return [self popoverControllerWithSender:aSender - permittedArrowDirections:aArrowDirections - animated:aAnimated - options:WYPopoverAnimationOptionFade]; -} - -- (WYPopoverController *)popoverControllerWithSender:(id)aSender - permittedArrowDirections:(WYPopoverArrowDirection)aArrowDirections - animated:(BOOL)aAnimated - options:(WYPopoverAnimationOptions)aOptions -{ - _sender = aSender; - _arrowDirections = aArrowDirections; - _animated = aAnimated; - _options = aOptions; - - _popoverController = [[WYPopoverController alloc] initWithContentViewController:self.destinationViewController]; - - return _popoverController; -} - -- (void)dealloc -{ - _sender = nil; - _popoverController = nil; -} - -@end