mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-08-05 16:58:59 +00:00

- I managed to reproduce the layout issue, so have implemented a check and correction for it.
1215 lines
60 KiB
Objective-C
1215 lines
60 KiB
Objective-C
//
|
|
// NBContainerViewController.m
|
|
// NewsBlur
|
|
//
|
|
// Created by Roy Yang on 7/24/12.
|
|
// Copyright (c) 2012 NewsBlur. All rights reserved.
|
|
//
|
|
|
|
#import "NBContainerViewController.h"
|
|
#import "NewsBlurViewController.h"
|
|
#import "FeedDetailViewController.h"
|
|
#import "DashboardViewController.h"
|
|
#import "StoryDetailViewController.h"
|
|
#import "StoryPageControl.h"
|
|
#import "OriginalStoryViewController.h"
|
|
#import "ShareViewController.h"
|
|
#import "UserProfileViewController.h"
|
|
#import "InteractionCell.h"
|
|
#import "ActivityCell.h"
|
|
#import "FeedTableCell.h"
|
|
#import "FeedDetailTableCell.h"
|
|
#import "FeedsMenuViewController.h"
|
|
#import "FontSettingsViewController.h"
|
|
#import "AddSiteViewController.h"
|
|
#import "TrainerViewController.h"
|
|
#import "NotificationsViewController.h"
|
|
#import "StoriesCollection.h"
|
|
#import "UserTagsViewController.h"
|
|
|
|
#define NB_DEFAULT_MASTER_WIDTH 270
|
|
#define NB_DEFAULT_MASTER_WIDTH_LANDSCAPE 370
|
|
#define NB_DEFAULT_SLIDER_INTERVAL 0.3
|
|
#define NB_DEFAULT_SLIDER_INTERVAL_OUT 0.3
|
|
#define NB_DEFAULT_SHARE_HEIGHT 144
|
|
#define NB_STORY_TITLES_BOTTOM_MIN_HEIGHT 80
|
|
|
|
@interface NBContainerViewController ()
|
|
|
|
@property (nonatomic, strong) UINavigationController *masterNavigationController;
|
|
@property (nonatomic, strong) UINavigationController *storyNavigationController;
|
|
@property (nonatomic, strong) UINavigationController *shareNavigationController;
|
|
@property (nonatomic, strong) UINavigationController *originalNavigationController;
|
|
@property (nonatomic, strong) NewsBlurViewController *feedsViewController;
|
|
@property (nonatomic, strong) FeedDetailViewController *feedDetailViewController;
|
|
@property (nonatomic, strong) DashboardViewController *dashboardViewController;
|
|
@property (nonatomic, strong) StoryDetailViewController *storyDetailViewController;
|
|
@property (nonatomic, strong) OriginalStoryViewController *originalViewController;
|
|
@property (nonatomic, strong) StoryPageControl *storyPageControl;
|
|
@property (nonatomic, strong) ShareViewController *shareViewController;
|
|
@property (nonatomic, strong) UIView *storyTitlesStub;
|
|
@property (readwrite) BOOL storyTitlesOnLeft;
|
|
@property (readwrite) int storyTitlesYCoordinate;
|
|
|
|
@property (readwrite) BOOL isSharingStory;
|
|
@property (readwrite) BOOL isHidingStory;
|
|
@property (readwrite) BOOL feedDetailIsVisible;
|
|
@property (readwrite) BOOL keyboardIsShown;
|
|
@property (nonatomic) UIBackgroundTaskIdentifier reorientBackgroundTask;
|
|
|
|
@end
|
|
|
|
@implementation NBContainerViewController
|
|
|
|
@synthesize appDelegate;
|
|
@synthesize masterNavigationController;
|
|
@synthesize shareNavigationController;
|
|
@synthesize originalNavigationController;
|
|
@synthesize feedsViewController;
|
|
@synthesize feedDetailViewController;
|
|
@synthesize dashboardViewController;
|
|
@synthesize storyDetailViewController;
|
|
@synthesize originalViewController;
|
|
@synthesize storyPageControl;
|
|
@synthesize shareViewController;
|
|
@synthesize feedDetailIsVisible;
|
|
@synthesize originalViewIsVisible;
|
|
@synthesize keyboardIsShown;
|
|
@synthesize storyNavigationController;
|
|
@synthesize storyTitlesYCoordinate;
|
|
@synthesize storyTitlesOnLeft;
|
|
@synthesize storyTitlesStub;
|
|
@synthesize isSharingStory;
|
|
@synthesize isHidingStory;
|
|
@synthesize leftBorder;
|
|
@synthesize rightBorder;
|
|
@synthesize interactiveOriginalTransition;
|
|
|
|
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
|
{
|
|
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
|
if (self) {
|
|
// Custom initialization
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)viewDidLoad {
|
|
[super viewDidLoad];
|
|
// Do any additional setup after loading the view.
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(keyboardWillShowOrHide:)
|
|
name:UIKeyboardWillShowNotification
|
|
object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(keyboardWillShowOrHide:)
|
|
name:UIKeyboardWillHideNotification
|
|
object:nil];
|
|
|
|
self.navigationController.navigationBar.translucent = NO;
|
|
self.masterNavigationController.navigationBar.translucent = NO;
|
|
|
|
self.masterNavigationController = appDelegate.navigationController;
|
|
self.feedsViewController = appDelegate.feedsViewController;
|
|
self.dashboardViewController = appDelegate.dashboardViewController;
|
|
self.feedDetailViewController = appDelegate.feedDetailViewController;
|
|
self.storyDetailViewController = appDelegate.storyDetailViewController;
|
|
self.originalViewController = appDelegate.originalStoryViewController;
|
|
self.storyPageControl = appDelegate.storyPageControl;
|
|
self.shareViewController = appDelegate.shareViewController;
|
|
|
|
// adding dashboardViewController
|
|
[self addChildViewController:self.dashboardViewController];
|
|
[self.view addSubview:self.dashboardViewController.view];
|
|
[self.dashboardViewController didMoveToParentViewController:self];
|
|
|
|
// adding master navigation controller
|
|
[self addChildViewController:self.masterNavigationController];
|
|
[self.view addSubview:self.masterNavigationController.view];
|
|
[self.masterNavigationController didMoveToParentViewController:self];
|
|
|
|
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.storyPageControl];
|
|
self.storyNavigationController = nav;
|
|
self.storyNavigationController.navigationBar.translucent = NO;
|
|
self.storyNavigationController.view.layer.masksToBounds = NO;
|
|
self.storyNavigationController.view.layer.shadowRadius = 5;
|
|
self.storyNavigationController.view.layer.shadowOpacity = 0.5;
|
|
self.storyNavigationController.view.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.view.bounds].CGPath;
|
|
|
|
UINavigationController *shareNav = [[UINavigationController alloc] initWithRootViewController:self.shareViewController];
|
|
self.shareNavigationController = shareNav;
|
|
self.shareNavigationController.navigationBar.translucent = NO;
|
|
|
|
UINavigationController *originalNav = [[UINavigationController alloc]
|
|
initWithRootViewController:originalViewController];
|
|
self.originalNavigationController = originalNav;
|
|
self.originalNavigationController.navigationBar.translucent = NO;
|
|
[self.originalNavigationController.interactivePopGestureRecognizer
|
|
addTarget:self
|
|
action:@selector(handleOriginalNavGesture:)];
|
|
|
|
// set up story titles stub
|
|
UIView * storyTitlesPlaceholder = [[UIView alloc] initWithFrame:CGRectZero];
|
|
storyTitlesPlaceholder.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
storyTitlesPlaceholder.autoresizesSubviews = YES;
|
|
storyTitlesPlaceholder.backgroundColor = UIColorFromRGB(NEWSBLUR_WHITE_COLOR);
|
|
|
|
self.storyTitlesStub = storyTitlesPlaceholder;
|
|
|
|
leftBorder = [CALayer layer];
|
|
leftBorder.frame = CGRectMake(0, 0, 1, CGRectGetHeight(self.view.bounds));
|
|
leftBorder.backgroundColor = UIColorFromRGB(0xC2C5BE).CGColor;
|
|
[self.storyNavigationController.view.layer addSublayer:leftBorder];
|
|
|
|
rightBorder = [CALayer layer];
|
|
rightBorder.frame = CGRectMake(self.masterWidth-1, 0, 1, CGRectGetHeight(self.view.bounds));
|
|
rightBorder.backgroundColor = UIColorFromRGB(0xC2C5BE).CGColor;
|
|
[self.masterNavigationController.view.layer addSublayer:rightBorder];
|
|
|
|
[self setupStoryTitlesPosition];
|
|
}
|
|
|
|
- (void)viewWillAppear:(BOOL)animated {
|
|
[super viewWillAppear:animated];
|
|
|
|
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
|
|
[self checkSize:self.view.bounds.size];
|
|
}
|
|
|
|
[self layoutDashboardScreen];
|
|
}
|
|
|
|
- (void)viewDidUnload {
|
|
[super viewDidUnload];
|
|
// Release any retained subviews of the main view.
|
|
}
|
|
|
|
- (void)viewDidAppear:(BOOL)animated {
|
|
[super viewDidAppear:animated];
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
}
|
|
|
|
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
|
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
|
|
|
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
|
|
[self checkSize:size];
|
|
}
|
|
|
|
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
|
// leftBorder.frame = CGRectMake(0, 0, 1, CGRectGetHeight(self.view.bounds));
|
|
|
|
if (UIInterfaceOrientationIsPortrait(orientation) && !self.storyTitlesOnLeft) {
|
|
leftBorder.hidden = YES;
|
|
} else {
|
|
leftBorder.hidden = NO;
|
|
}
|
|
|
|
[self adjustLayoutCompleted:NO];
|
|
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
|
// leftBorder.frame = CGRectMake(0, 0, 1, CGRectGetHeight(self.view.bounds));
|
|
|
|
CGFloat currentMasterWidth = self.masterNavigationController.view.frame.size.width;
|
|
BOOL isInvalid = currentMasterWidth < 100.0;
|
|
|
|
if (isInvalid) {
|
|
NSLog(@"Invalid width detected: %@; correcting", @(currentMasterWidth)); // log
|
|
|
|
self.masterNavigationController.view.frame = CGRectMake(0, 0, self.masterWidth, self.view.bounds.size.height);
|
|
}
|
|
|
|
if (!self.feedDetailIsVisible) {
|
|
[self adjustLayoutCompleted:YES];
|
|
}
|
|
|
|
if (self.feedDetailIsVisible) {
|
|
// Defer this in the background, to avoid misaligning the detail views
|
|
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
|
|
self.reorientBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
|
[[UIApplication sharedApplication] endBackgroundTask:self.reorientBackgroundTask];
|
|
self.reorientBackgroundTask = UIBackgroundTaskInvalid;
|
|
}];
|
|
[self performSelector:@selector(delayedReorientPages) withObject:nil afterDelay:0.5];
|
|
} else {
|
|
[self.storyPageControl reorientPages];
|
|
}
|
|
}
|
|
}];
|
|
}
|
|
|
|
- (BOOL)prefersStatusBarHidden {
|
|
if (@available(iOS 11.0, *)) {
|
|
return self.navigationController.navigationBarHidden && self.view.safeAreaInsets.top > 0.0;
|
|
} else {
|
|
return self.navigationController.navigationBarHidden;
|
|
}
|
|
}
|
|
|
|
- (void)adjustLayoutCompleted:(BOOL)completed {
|
|
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground && !completed) {
|
|
return;
|
|
}
|
|
|
|
if (!self.feedDetailIsVisible) {
|
|
[self layoutDashboardScreen];
|
|
} else if (!self.originalViewIsVisible) {
|
|
[self layoutFeedDetailScreen];
|
|
}
|
|
}
|
|
|
|
- (void)delayedReorientPages {
|
|
[self.storyPageControl reorientPages];
|
|
[[UIApplication sharedApplication] endBackgroundTask:self.reorientBackgroundTask];
|
|
self.reorientBackgroundTask = UIBackgroundTaskInvalid;
|
|
}
|
|
|
|
- (void)checkSize:(CGSize)size {
|
|
BOOL wasCompact = self.appDelegate.isCompactWidth;
|
|
BOOL isCompact = size.width < 700.0;
|
|
|
|
if (!isCompact && wasCompact == isCompact) {
|
|
return;
|
|
}
|
|
|
|
self.appDelegate.compactWidth = isCompact ? size.width : 0.0;
|
|
|
|
self.masterNavigationController.view.frame = CGRectMake(0, 0, self.masterWidth, self.view.bounds.size.height);
|
|
|
|
if (!isCompact) {
|
|
if (self.masterNavigationController.topViewController == self.storyPageControl) {
|
|
[self.masterNavigationController popToViewController:self.feedDetailViewController animated:NO];
|
|
}
|
|
|
|
if (self.storyNavigationController.topViewController != self.storyPageControl) {
|
|
[self.storyNavigationController pushViewController:self.storyPageControl animated:NO];
|
|
self.storyPageControl.isAnimatedIntoPlace = NO;
|
|
}
|
|
|
|
[self.storyPageControl hidePages];
|
|
}
|
|
}
|
|
|
|
- (NSInteger)masterWidth {
|
|
if (self.appDelegate.isCompactWidth) {
|
|
return self.appDelegate.compactWidth;
|
|
}
|
|
|
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
|
if (UIInterfaceOrientationIsLandscape(orientation)) {
|
|
return NB_DEFAULT_MASTER_WIDTH_LANDSCAPE;
|
|
}
|
|
return NB_DEFAULT_MASTER_WIDTH;
|
|
}
|
|
|
|
- (UIStatusBarStyle)preferredStatusBarStyle {
|
|
if ([ThemeManager themeManager].isDarkTheme) {
|
|
return UIStatusBarStyleLightContent;
|
|
} else {
|
|
return UIStatusBarStyleDefault;
|
|
}
|
|
}
|
|
|
|
- (void)updateTheme {
|
|
self.leftBorder.backgroundColor = UIColorFromRGB(0xC2C5BE).CGColor;
|
|
self.rightBorder.backgroundColor = UIColorFromRGB(0xC2C5BE).CGColor;
|
|
|
|
self.view.backgroundColor = UIColor.blackColor;
|
|
|
|
self.masterNavigationController.navigationBar.tintColor = [UINavigationBar appearance].tintColor;
|
|
self.masterNavigationController.navigationBar.barTintColor = [UINavigationBar appearance].barTintColor;
|
|
|
|
self.storyNavigationController.navigationBar.tintColor = [UINavigationBar appearance].tintColor;
|
|
self.storyNavigationController.navigationBar.barTintColor = [UINavigationBar appearance].barTintColor;
|
|
|
|
self.originalNavigationController.navigationBar.tintColor = [UINavigationBar appearance].tintColor;
|
|
self.originalNavigationController.navigationBar.barTintColor = [UINavigationBar appearance].barTintColor;
|
|
|
|
UIView *titleLabel = [appDelegate makeFeedTitle:appDelegate.storiesCollection.activeFeed];
|
|
self.storyPageControl.navigationItem.titleView = titleLabel;
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark State Restoration
|
|
|
|
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
|
|
[super encodeRestorableStateWithCoder:coder];
|
|
|
|
[coder encodeBool:self.feedDetailIsVisible forKey:@"feedDetailIsVisible"];
|
|
[coder encodeBool:self.originalViewIsVisible forKey:@"originalViewIsVisible"];
|
|
|
|
if (self.feedDetailIsVisible) {
|
|
[self.feedDetailViewController encodeRestorableStateWithCoder:coder];
|
|
[self.storyPageControl encodeRestorableStateWithCoder:coder];
|
|
}
|
|
}
|
|
|
|
- (void)decodeRestorableStateWithCoder:(NSCoder *)coder {
|
|
[super decodeRestorableStateWithCoder:coder];
|
|
|
|
if ([coder decodeBoolForKey:@"feedDetailIsVisible"]) {
|
|
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: @"All"
|
|
style: UIBarButtonItemStylePlain
|
|
target: nil
|
|
action: nil];
|
|
[self.feedsViewController.navigationItem setBackBarButtonItem: newBackButton];
|
|
|
|
[self transitionToFeedDetail:YES animated:NO];
|
|
[self.feedDetailViewController decodeRestorableStateWithCoder:coder];
|
|
[self.storyPageControl decodeRestorableStateWithCoder:coder];
|
|
}
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark Modals and Popovers
|
|
|
|
- (void)showUserProfilePopover:(id)sender {
|
|
if ([sender class] == [InteractionCell class] ||
|
|
[sender class] == [ActivityCell class]) {
|
|
InteractionCell *cell = (InteractionCell *)sender;
|
|
|
|
[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.appDelegate showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) sourceView:cell sourceRect:cell.bounds];
|
|
} else if ([sender class] == [UIBarButtonItem class]) {
|
|
[self.appDelegate showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) barButtonItem:sender];
|
|
} else {
|
|
CGRect frame = [sender CGRectValue];
|
|
[self.appDelegate showPopoverWithViewController:self.appDelegate.userProfileNavigationController contentSize:CGSizeMake(320, 454) sourceView:self.storyPageControl.view sourceRect:frame];
|
|
}
|
|
}
|
|
|
|
- (void)showTrainingPopover:(id)sender {
|
|
if ([sender class] == [UIBarButtonItem class]) {
|
|
[self.appDelegate showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) barButtonItem:sender];
|
|
} else if ([sender class] == [FeedTableCell class]) {
|
|
FeedTableCell *cell = (FeedTableCell *)sender;
|
|
[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.appDelegate showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) sourceView:cell sourceRect:cell.bounds];
|
|
} else {
|
|
CGRect frame = [sender CGRectValue];
|
|
[self.appDelegate showPopoverWithViewController:self.appDelegate.trainerViewController contentSize:CGSizeMake(420, 382) sourceView:self.storyPageControl.view sourceRect:frame];
|
|
}
|
|
}
|
|
|
|
|
|
- (void)showNotificationsPopoverWithFeed:(NSString *)feedId sender:(id)sender {
|
|
self.appDelegate.notificationsViewController.feedId = feedId;
|
|
if ([sender class] == [UIBarButtonItem class]) {
|
|
[self.appDelegate showPopoverWithViewController:self.appDelegate.notificationsViewController contentSize:CGSizeMake(420, 382) barButtonItem:sender];
|
|
} else if ([sender class] == [FeedTableCell class]) {
|
|
FeedTableCell *cell = (FeedTableCell *)sender;
|
|
[self.appDelegate showPopoverWithViewController:self.appDelegate.notificationsViewController contentSize:CGSizeMake(420, 382) sourceView:cell sourceRect:cell.bounds];
|
|
} else if ([sender class] == [FeedDetailTableCell class]) {
|
|
FeedDetailTableCell *cell = (FeedDetailTableCell *)sender;
|
|
[self.appDelegate showPopoverWithViewController:self.appDelegate.notificationsViewController contentSize:CGSizeMake(420, 382) sourceView:cell sourceRect:cell.bounds];
|
|
} else {
|
|
[self.appDelegate showPopoverWithViewController:self.appDelegate.notificationsViewController contentSize:CGSizeMake(420, 382) barButtonItem:appDelegate.feedsViewController.settingsBarButton];
|
|
}
|
|
}
|
|
|
|
- (void)syncNextPreviousButtons {
|
|
[self.storyPageControl setNextPreviousButtons];
|
|
}
|
|
|
|
#pragma mark - UIPopoverPresentationControllerDelegate
|
|
|
|
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
|
|
return UIModalPresentationNone;
|
|
}
|
|
|
|
#pragma mark - Screen Transitions and Layout
|
|
|
|
- (void)setupStoryTitlesPosition {
|
|
// set default y coordinate for feedDetailY from saved preferences
|
|
CGRect vb = [self.view bounds];
|
|
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
|
|
int savedStoryTitlesYCoordinate = (int)[userPreferences integerForKey:@"storyTitlesYCoordinate"];
|
|
NSString *storyTitlesPosition = [userPreferences stringForKey:@"story_titles_position"];
|
|
if ([storyTitlesPosition isEqualToString:@"titles_on_bottom"]) {
|
|
if (!savedStoryTitlesYCoordinate || savedStoryTitlesYCoordinate > CGRectGetHeight(vb) - NB_STORY_TITLES_BOTTOM_MIN_HEIGHT) {
|
|
savedStoryTitlesYCoordinate = CGRectGetHeight(vb) - NB_STORY_TITLES_BOTTOM_MIN_HEIGHT;
|
|
}
|
|
self.storyTitlesYCoordinate = savedStoryTitlesYCoordinate;
|
|
self.storyTitlesOnLeft = NO;
|
|
} else {
|
|
self.storyTitlesYCoordinate = CGRectGetHeight(vb);
|
|
self.storyTitlesOnLeft = YES;
|
|
}
|
|
}
|
|
|
|
- (void)layoutDashboardScreen {
|
|
CGRect vb = [self.view bounds];
|
|
self.masterNavigationController.view.frame = CGRectMake(0, 0, self.masterWidth, vb.size.height);
|
|
self.dashboardViewController.view.frame = CGRectMake(self.masterWidth, 0, vb.size.width - self.masterWidth, vb.size.height);
|
|
rightBorder.frame = CGRectMake(self.masterWidth-1, 0, 1, CGRectGetHeight(self.view.bounds));
|
|
self.storyPageControl.navigationItem.leftBarButtonItem = self.storyPageControl.buttonBack;
|
|
}
|
|
|
|
- (void)layoutFeedDetailScreen {
|
|
CGRect vb = [self.view bounds];
|
|
rightBorder.frame = CGRectMake(self.masterWidth-1, 0, 1, CGRectGetHeight(self.view.bounds));
|
|
|
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
|
if (UIInterfaceOrientationIsPortrait(orientation) && !self.storyTitlesOnLeft) {
|
|
// add the back button
|
|
self.storyPageControl.navigationItem.leftBarButtonItem = self.storyPageControl.buttonBack;
|
|
|
|
// set center title
|
|
UIView *titleLabel = [appDelegate makeFeedTitle:appDelegate.storiesCollection.activeFeed];
|
|
self.storyPageControl.navigationItem.titleView = titleLabel;
|
|
|
|
if ([[self.masterNavigationController viewControllers] containsObject:self.feedDetailViewController]) {
|
|
[self.masterNavigationController popViewControllerAnimated:NO];
|
|
}
|
|
self.storyNavigationController.view.frame = CGRectMake(0, 0,
|
|
vb.size.width,
|
|
self.storyTitlesYCoordinate);
|
|
self.feedDetailViewController.view.frame = CGRectMake(0, self.storyTitlesYCoordinate,
|
|
vb.size.width,
|
|
vb.size.height -
|
|
self.storyTitlesYCoordinate);
|
|
[self.view insertSubview:self.feedDetailViewController.view
|
|
aboveSubview:self.storyNavigationController.view];
|
|
[self.masterNavigationController.view removeFromSuperview];
|
|
[self.dashboardViewController.view removeFromSuperview];
|
|
self.originalNavigationController.view.frame = CGRectMake(vb.size.width, 0,
|
|
vb.size.width, vb.size.height);
|
|
} else {
|
|
// remove the back button
|
|
self.storyPageControl.navigationItem.leftBarButtonItem = nil;
|
|
|
|
if (![[self.masterNavigationController viewControllers] containsObject:self.feedDetailViewController]) {
|
|
[self.masterNavigationController pushViewController:self.feedDetailViewController animated:NO];
|
|
}
|
|
[self.view addSubview:self.masterNavigationController.view];
|
|
self.masterNavigationController.view.frame = CGRectMake(0, 0, self.masterWidth, vb.size.height);
|
|
self.storyNavigationController.view.frame = CGRectMake(self.masterWidth-1, 0, vb.size.width - self.masterWidth + 1, vb.size.height);
|
|
[self.dashboardViewController.view removeFromSuperview];
|
|
self.originalNavigationController.view.frame = CGRectMake(vb.size.width, 0, vb.size.width, vb.size.height);
|
|
// leftBorder.frame = CGRectMake(0, 0, 1, CGRectGetHeight(self.view.bounds));
|
|
// NSLog(@"Transitioning back to feed detail, original frame: %@", NSStringFromCGRect(self.originalNavigationController.view.frame));
|
|
}
|
|
}
|
|
|
|
- (void)adjustFeedDetailScreenForStoryTitles {
|
|
CGRect vb = [self.view bounds];
|
|
CGFloat bottomMargin = 80.f;
|
|
|
|
if (!self.storyTitlesOnLeft) {
|
|
if (self.storyTitlesYCoordinate > CGRectGetHeight(vb) - bottomMargin) {
|
|
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
|
|
// save coordinate
|
|
[userPreferences setInteger:CGRectGetHeight(vb) - bottomMargin forKey:@"storyTitlesYCoordinate"];
|
|
[userPreferences setValue:@"titles_on_left" forKey:@"story_titles_position"];
|
|
[userPreferences synchronize];
|
|
self.storyTitlesYCoordinate = CGRectGetHeight(vb) - bottomMargin;
|
|
// slide to the left
|
|
|
|
self.storyTitlesOnLeft = YES;
|
|
self.leftBorder.hidden = NO;
|
|
|
|
// remove the back button
|
|
self.storyPageControl.navigationItem.leftBarButtonItem = nil;
|
|
|
|
// remove center title
|
|
self.storyPageControl.navigationItem.titleView = nil;
|
|
|
|
[self.masterNavigationController popToRootViewControllerAnimated:NO];
|
|
if (![[self.masterNavigationController viewControllers] containsObject:self.feedDetailViewController]) {
|
|
[self.masterNavigationController pushViewController:self.feedDetailViewController animated:NO];
|
|
}
|
|
[self.view addSubview:self.masterNavigationController.view];
|
|
|
|
self.masterNavigationController.view.frame = CGRectMake(-1 * self.masterWidth, 0, self.masterWidth, vb.size.height);
|
|
[UIView animateWithDuration:NB_DEFAULT_SLIDER_INTERVAL delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
|
self.masterNavigationController.view.frame = CGRectMake(0, 0, self.masterWidth, vb.size.height);
|
|
self.storyNavigationController.view.frame = CGRectMake(self.masterWidth-1, 0, vb.size.width - self.masterWidth + 1, vb.size.height);
|
|
} completion:^(BOOL finished) {
|
|
[self.feedDetailViewController checkScroll];
|
|
[appDelegate.storyPageControl refreshPages];
|
|
[appDelegate adjustStoryDetailWebView];
|
|
[self.feedDetailViewController.storyTitlesTable reloadData];
|
|
}];
|
|
}
|
|
} else if (self.storyTitlesOnLeft) {
|
|
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
|
|
|
|
if (self.storyTitlesYCoordinate == CGRectGetHeight(vb)) {
|
|
return;
|
|
} else if (self.storyTitlesYCoordinate > (CGRectGetHeight(vb)-bottomMargin)) {
|
|
// save coordinate
|
|
[userPreferences setInteger:CGRectGetHeight(vb)-bottomMargin forKey:@"storyTitlesYCoordinate"];
|
|
[userPreferences synchronize];
|
|
self.storyTitlesYCoordinate = CGRectGetHeight(vb)-bottomMargin;
|
|
}
|
|
|
|
[userPreferences setValue:@"titles_on_bottom" forKey:@"story_titles_position"];
|
|
[userPreferences synchronize];
|
|
|
|
self.storyTitlesOnLeft = NO;
|
|
self.leftBorder.hidden = YES;
|
|
|
|
// add the back button
|
|
self.storyPageControl.navigationItem.leftBarButtonItem = self.storyPageControl.buttonBack;
|
|
|
|
// set center title
|
|
UIView *titleLabel = [appDelegate makeFeedTitle:appDelegate.storiesCollection.activeFeed];
|
|
self.storyPageControl.navigationItem.titleView = titleLabel;
|
|
|
|
[UIView animateWithDuration:NB_DEFAULT_SLIDER_INTERVAL delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
|
self.masterNavigationController.view.frame = CGRectMake(-1 * self.masterWidth, 0, self.masterWidth, vb.size.height);
|
|
|
|
self.storyNavigationController.view.frame = CGRectMake(0, 0, vb.size.width, storyTitlesYCoordinate);
|
|
|
|
self.storyTitlesStub.frame = CGRectMake(0, storyTitlesYCoordinate, vb.size.width, vb.size.height - storyTitlesYCoordinate - 44 - 20);
|
|
} completion:^(BOOL finished) {
|
|
[self.view insertSubview:self.feedDetailViewController.view
|
|
aboveSubview:self.storyTitlesStub];
|
|
self.feedDetailViewController.view.frame = CGRectMake(0, storyTitlesYCoordinate, vb.size.width, vb.size.height - storyTitlesYCoordinate);
|
|
self.storyTitlesStub.hidden = YES;
|
|
[self.feedDetailViewController checkScroll];
|
|
[appDelegate.storyPageControl refreshPages];
|
|
[appDelegate adjustStoryDetailWebView];
|
|
[self.feedDetailViewController.storyTitlesTable reloadData];
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)transitionToFeedDetail {
|
|
[self transitionToFeedDetail:YES];
|
|
}
|
|
|
|
- (void)transitionToFeedDetail:(BOOL)resetLayout {
|
|
[self transitionToFeedDetail:resetLayout animated:YES];
|
|
}
|
|
|
|
- (void)transitionToFeedDetail:(BOOL)resetLayout animated:(BOOL)animated {
|
|
[self.appDelegate hidePopover];
|
|
if (self.feedDetailIsVisible) resetLayout = NO;
|
|
self.feedDetailIsVisible = YES;
|
|
|
|
if (resetLayout) {
|
|
// adding storyDetailViewController
|
|
[self addChildViewController:self.storyNavigationController];
|
|
[self.view addSubview:self.storyNavigationController.view];
|
|
[self.storyNavigationController didMoveToParentViewController:self];
|
|
|
|
// adding feedDetailViewController
|
|
// [self addChildViewController:self.feedDetailViewController];
|
|
// [self.view insertSubview:self.feedDetailViewController.view
|
|
// aboveSubview:self.storyNavigationController.view];
|
|
// [self.feedDetailViewController didMoveToParentViewController:self];
|
|
|
|
[self.view insertSubview:self.storyTitlesStub
|
|
aboveSubview:self.storyNavigationController.view];
|
|
|
|
// reset the storyDetailViewController components
|
|
self.storyPageControl.currentPage.webView.hidden = YES;
|
|
self.storyPageControl.nextPage.webView.hidden = YES;
|
|
self.storyPageControl.navigationItem.rightBarButtonItems = nil;
|
|
[self.storyPageControl hidePages];
|
|
NSInteger unreadCount = appDelegate.unreadCount;
|
|
if (unreadCount == 0) {
|
|
self.storyPageControl.circularProgressView.percentage = 1;
|
|
} else {
|
|
self.storyPageControl.circularProgressView.percentage = 0;
|
|
}
|
|
|
|
UIView *titleLabel = [appDelegate makeFeedTitle:appDelegate.storiesCollection.activeFeed];
|
|
self.storyPageControl.navigationItem.titleView = titleLabel;
|
|
|
|
[self setupStoryTitlesPosition];
|
|
}
|
|
|
|
CGRect vb = [self.view bounds];
|
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
|
if (UIInterfaceOrientationIsPortrait(orientation) && !self.storyTitlesOnLeft) {
|
|
// Force the story page control to load.
|
|
[storyPageControl view];
|
|
// CASE: story titles on bottom
|
|
if (resetLayout) {
|
|
self.storyPageControl.navigationItem.leftBarButtonItem = self.storyPageControl.buttonBack;
|
|
self.storyPageControl.navigationItem.rightBarButtonItems = self.feedDetailViewController.navigationItem.rightBarButtonItems;
|
|
|
|
[self.view insertSubview:self.feedDetailViewController.view
|
|
aboveSubview:self.storyNavigationController.view];
|
|
|
|
self.storyNavigationController.view.frame = CGRectMake(vb.size.width, 0, vb.size.width, storyTitlesYCoordinate);
|
|
self.feedDetailViewController.view.frame = CGRectMake(vb.size.width,
|
|
self.storyTitlesYCoordinate,
|
|
vb.size.width,
|
|
vb.size.height - storyTitlesYCoordinate);
|
|
}
|
|
float largeTimeInterval = NB_DEFAULT_SLIDER_INTERVAL * ( vb.size.width - self.masterWidth) / vb.size.width;
|
|
float smallTimeInterval = NB_DEFAULT_SLIDER_INTERVAL * self.masterWidth / vb.size.width;
|
|
|
|
[UIView animateWithDuration:largeTimeInterval delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
|
|
self.storyNavigationController.view.frame = CGRectMake(self.masterWidth, 0, vb.size.width, self.storyTitlesYCoordinate);
|
|
self.feedDetailViewController.view.frame = CGRectMake(self.masterWidth,
|
|
self.storyTitlesYCoordinate,
|
|
vb.size.width,
|
|
vb.size.height - storyTitlesYCoordinate);
|
|
} completion:^(BOOL finished) {
|
|
self.leftBorder.hidden = YES;
|
|
[UIView animateWithDuration:smallTimeInterval delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
|
self.storyNavigationController.view.frame = CGRectMake(0, 0, vb.size.width, self.storyTitlesYCoordinate);
|
|
self.feedDetailViewController.view.frame = CGRectMake(0, self.storyTitlesYCoordinate, vb.size.width, vb.size.height - storyTitlesYCoordinate);
|
|
self.masterNavigationController.view.frame = CGRectMake(-1 * self.masterWidth, 0, self.masterWidth, vb.size.height);
|
|
} completion:^(BOOL finished) {
|
|
self.feedDetailIsVisible = YES;
|
|
|
|
[self.dashboardViewController.view removeFromSuperview];
|
|
[self.masterNavigationController.view removeFromSuperview];
|
|
}];
|
|
}];
|
|
} else {
|
|
// CASE: story titles on left
|
|
if (resetLayout) {
|
|
self.storyNavigationController.view.frame = CGRectMake(vb.size.width, 0,
|
|
vb.size.width - (self.masterWidth-1),
|
|
vb.size.height);
|
|
[self.masterNavigationController
|
|
pushViewController:self.feedDetailViewController
|
|
animated:animated];
|
|
[self interactiveTransitionFromFeedDetail:1];
|
|
|
|
UIView *titleLabel = [appDelegate makeFeedTitle:appDelegate.storiesCollection.activeFeed];
|
|
self.storyPageControl.navigationItem.titleView = titleLabel;
|
|
}
|
|
self.leftBorder.hidden = NO;
|
|
|
|
if (animated) {
|
|
[UIView animateWithDuration:.35 delay:0
|
|
options:UIViewAnimationOptionCurveEaseOut
|
|
animations:^{
|
|
[self interactiveTransitionFromFeedDetail:0];
|
|
} completion:^(BOOL finished) {
|
|
self.feedDetailIsVisible = YES;
|
|
// NSLog(@"Finished hiding dashboard: %d", finished);
|
|
// [self.dashboardViewController.view removeFromSuperview];
|
|
}];
|
|
} else {
|
|
[self interactiveTransitionFromFeedDetail:0];
|
|
self.feedDetailIsVisible = YES;
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)handleOriginalNavGesture:(UIScreenEdgePanGestureRecognizer *)gesture {
|
|
if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) return;
|
|
|
|
self.interactiveOriginalTransition = YES;
|
|
|
|
CGPoint point = [gesture locationInView:self.view];
|
|
CGFloat viewWidth = CGRectGetWidth(self.view.bounds);
|
|
CGFloat percentage = MIN(point.x, viewWidth) / viewWidth;
|
|
// NSLog(@"back gesture: %d, %f - %f/%f", (int)gesture.state, percentage, point.x, viewWidth);
|
|
|
|
if (gesture.state == UIGestureRecognizerStateChanged) {
|
|
[appDelegate.masterContainerViewController interactiveTransitionFromOriginalView:percentage];
|
|
} else if (gesture.state == UIGestureRecognizerStateEnded) {
|
|
CGPoint velocity = [gesture velocityInView:self.view];
|
|
if (velocity.x > 0) {
|
|
[appDelegate.masterContainerViewController transitionFromOriginalView];
|
|
} else {
|
|
// Returning back to view, cancelling pop animation.
|
|
[appDelegate.masterContainerViewController transitionToOriginalView:NO];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)transitionToOriginalView {
|
|
[self transitionToOriginalView:YES];
|
|
}
|
|
|
|
- (void)transitionToOriginalView:(BOOL)resetLayout {
|
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
|
CGRect vb = [self.view bounds];
|
|
|
|
self.originalViewIsVisible = YES;
|
|
self.originalViewController = appDelegate.originalStoryViewController;
|
|
|
|
if (resetLayout) {
|
|
[self addChildViewController:self.originalNavigationController];
|
|
[self.originalNavigationController.view setHidden:NO];
|
|
if (![[self.originalNavigationController viewControllers]
|
|
containsObject:self.originalViewController]) {
|
|
[self.originalNavigationController pushViewController:self.originalViewController
|
|
animated:NO];
|
|
} else {
|
|
[self.originalViewController viewWillAppear:YES];
|
|
}
|
|
|
|
[self.view insertSubview:self.originalNavigationController.view
|
|
aboveSubview:self.masterNavigationController.view];
|
|
[self.originalNavigationController didMoveToParentViewController:self];
|
|
|
|
self.originalNavigationController.view.frame = CGRectMake(CGRectGetMaxX(vb),
|
|
0,
|
|
CGRectGetWidth(vb),
|
|
CGRectGetHeight(vb));
|
|
[self.originalViewController view]; // Force viewDidLoad
|
|
[self.originalViewController loadInitialStory];
|
|
}
|
|
|
|
self.originalViewController.navigationItem.titleView.alpha = 1;
|
|
self.originalViewController.navigationItem.leftBarButtonItem.customView.alpha = 1;
|
|
[self.originalViewController becomeFirstResponder];
|
|
|
|
[UIView animateWithDuration:.35 delay:0
|
|
options:UIViewAnimationOptionCurveEaseOut
|
|
animations:^
|
|
{
|
|
if (UIInterfaceOrientationIsPortrait(orientation) && !self.storyTitlesOnLeft) {
|
|
self.storyNavigationController.view.frame = CGRectMake(-100, 0, vb.size.width, self.storyTitlesYCoordinate);
|
|
self.feedDetailViewController.view.frame = CGRectMake(-100, self.storyTitlesYCoordinate, vb.size.width, vb.size.height - storyTitlesYCoordinate);
|
|
self.masterNavigationController.view.frame = CGRectMake(-1 * self.masterWidth, 0, self.masterWidth, vb.size.height);
|
|
} else {
|
|
self.masterNavigationController.view.frame = CGRectMake(-100, 0, self.masterWidth, vb.size.height);
|
|
self.storyNavigationController.view.frame = CGRectMake(-100 + self.masterWidth - 1, 0, vb.size.width - self.masterWidth + 1, vb.size.height);
|
|
}
|
|
|
|
self.originalNavigationController.view.frame = CGRectMake(0, 0,
|
|
CGRectGetWidth(vb),
|
|
CGRectGetHeight(vb));
|
|
CGRect frame = self.originalViewController.view.frame;
|
|
frame.origin.x = 0;
|
|
self.originalViewController.view.frame = frame;
|
|
} completion:^(BOOL finished) {
|
|
self.interactiveOriginalTransition = NO;
|
|
}];
|
|
}
|
|
|
|
- (void)transitionFromOriginalView {
|
|
// NSLog(@"Transition from Original View");
|
|
|
|
[self.originalViewController viewWillDisappear:YES];
|
|
self.originalViewIsVisible = NO;
|
|
|
|
[self.storyPageControl becomeFirstResponder];
|
|
|
|
[UIView animateWithDuration:0.35 delay:0
|
|
options:UIViewAnimationOptionCurveEaseOut
|
|
animations:^
|
|
{
|
|
[self layoutFeedDetailScreen];
|
|
} completion:^(BOOL finished) {
|
|
self.interactiveOriginalTransition = NO;
|
|
[self.originalNavigationController removeFromParentViewController];
|
|
[self.originalNavigationController.view setHidden:YES];
|
|
[self.originalViewController viewDidDisappear:YES];
|
|
}];
|
|
}
|
|
|
|
- (void)interactiveTransitionFromOriginalView:(CGFloat)percentage {
|
|
CGRect vb = [self.view bounds];
|
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
|
|
|
if (UIInterfaceOrientationIsPortrait(orientation) && !self.storyTitlesOnLeft) {
|
|
// CGRect originalNavFrame = self.originalNavigationController.view.frame;
|
|
// originalNavFrame.origin.x = vb.size.width * percentage;
|
|
// self.originalNavigationController.view.frame = originalNavFrame;
|
|
// self.originalViewController.view.frame = originalNavFrame;
|
|
// NSLog(@"Original frame: %@", NSStringFromCGRect(self.originalViewController.view.frame));
|
|
|
|
CGRect feedDetailFrame = self.feedDetailViewController.view.frame;
|
|
feedDetailFrame.origin.x = -1 * (1-percentage) * 100;
|
|
self.feedDetailViewController.view.frame = feedDetailFrame;
|
|
|
|
CGRect storyNavFrame = self.storyNavigationController.view.frame;
|
|
storyNavFrame.origin.x = -1 * (1-percentage) * 100;
|
|
self.storyNavigationController.view.frame = storyNavFrame;
|
|
} else {
|
|
CGRect originalNavFrame = self.originalNavigationController.view.frame;
|
|
originalNavFrame.origin.x = vb.size.width * percentage * 0;
|
|
// self.originalNavigationController.view.frame = originalNavFrame;
|
|
// self.originalViewController.view.frame = originalNavFrame;
|
|
// NSLog(@"Original frame: %@", NSStringFromCGRect([[[[self.originalNavigationController viewControllers] objectAtIndex:0] view] frame]));
|
|
|
|
CGRect feedDetailFrame = self.masterNavigationController.view.frame;
|
|
feedDetailFrame.origin.x = -1 * (1-percentage) * 100;
|
|
self.masterNavigationController.view.frame = feedDetailFrame;
|
|
|
|
CGRect storyNavFrame = self.storyNavigationController.view.frame;
|
|
storyNavFrame.origin.x = self.masterWidth - 1 + -1 * (1-percentage) * 100;
|
|
self.storyNavigationController.view.frame = storyNavFrame;
|
|
}
|
|
|
|
// self.originalNavigationController.navigationBar.alpha = 1 - percentage;
|
|
// NSLog(@"Original subviews; %@", self.originalNavigationController.view.subviews);
|
|
self.originalViewController.navigationItem.titleView.alpha = 1 - percentage;
|
|
self.originalViewController.navigationItem.leftBarButtonItem.customView.alpha = 1 - percentage;
|
|
// CGRect leftBorderFrame = leftBorder.frame;
|
|
// leftBorderFrame.origin.x = storyNavFrame.origin.x - 1;
|
|
// leftBorder.frame = leftBorderFrame;
|
|
}
|
|
|
|
- (void)interactiveTransitionFromFeedDetail:(CGFloat)percentage {
|
|
[self.view insertSubview:self.dashboardViewController.view atIndex:0];
|
|
[self.view addSubview:self.masterNavigationController.view];
|
|
|
|
CGRect storyNavFrame = self.storyNavigationController.view.frame;
|
|
storyNavFrame.origin.x = self.masterWidth - 1 + storyNavFrame.size.width * percentage;
|
|
self.storyNavigationController.view.frame = storyNavFrame;
|
|
|
|
CGRect dashboardFrame = self.dashboardViewController.view.frame;
|
|
dashboardFrame.origin.x = self.masterWidth + -1 * (1-percentage) * dashboardFrame.size.width/6;
|
|
self.dashboardViewController.view.frame = dashboardFrame;
|
|
}
|
|
|
|
- (void)transitionFromFeedDetail {
|
|
[self transitionFromFeedDetail:YES];
|
|
}
|
|
|
|
- (void)transitionFromFeedDetail:(BOOL)resetLayout {
|
|
if (!self.feedDetailIsVisible) {
|
|
return;
|
|
}
|
|
|
|
[self.appDelegate hidePopover];
|
|
|
|
if (self.isSharingStory) {
|
|
[self transitionFromShareView];
|
|
}
|
|
|
|
self.feedDetailIsVisible = NO;
|
|
CGRect vb = [self.view bounds];
|
|
|
|
[appDelegate.dashboardViewController.storiesModule reloadData];
|
|
|
|
// adding dashboardViewController and masterNavigationController
|
|
[self.view insertSubview:self.dashboardViewController.view atIndex:0];
|
|
[self.view addSubview:self.masterNavigationController.view];
|
|
|
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
|
if (UIInterfaceOrientationIsPortrait(orientation) && !self.storyTitlesOnLeft) {
|
|
// CASE: story titles on bottom
|
|
if (resetLayout) {
|
|
self.dashboardViewController.view.frame = CGRectMake(self.masterWidth, 0, vb.size.width - self.masterWidth, vb.size.height);
|
|
self.masterNavigationController.view.frame = CGRectMake(-1 * self.masterWidth, 0, self.masterWidth, vb.size.height);
|
|
}
|
|
float smallTimeInterval = NB_DEFAULT_SLIDER_INTERVAL_OUT * self.masterWidth / vb.size.width;
|
|
float largeTimeInterval = NB_DEFAULT_SLIDER_INTERVAL_OUT * ( vb.size.width - self.masterWidth) / vb.size.width;
|
|
[self.masterNavigationController popViewControllerAnimated:NO];
|
|
|
|
[UIView animateWithDuration:smallTimeInterval delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
|
|
self.masterNavigationController.view.frame = CGRectMake(0, 0, self.masterWidth, vb.size.height);
|
|
self.storyNavigationController.view.frame = CGRectMake(self.masterWidth - 1,
|
|
0,
|
|
vb.size.width,
|
|
self.storyTitlesYCoordinate);
|
|
self.feedDetailViewController.view.frame = CGRectMake(self.masterWidth,
|
|
self.storyTitlesYCoordinate,
|
|
vb.size.width,
|
|
vb.size.height - storyTitlesYCoordinate);
|
|
} completion:^(BOOL finished) {
|
|
if (self.feedDetailIsVisible) return;
|
|
|
|
self.leftBorder.hidden = NO;
|
|
[UIView animateWithDuration:largeTimeInterval delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
|
self.storyNavigationController.view.frame = CGRectMake(vb.size.width, 0, vb.size.width, self.storyTitlesYCoordinate);
|
|
self.feedDetailViewController.view.frame = CGRectMake(vb.size.width,
|
|
self.storyTitlesYCoordinate,
|
|
vb.size.width,
|
|
vb.size.height - storyTitlesYCoordinate);
|
|
} completion:^(BOOL finished) {
|
|
if (self.feedDetailIsVisible) return;
|
|
[self.storyNavigationController.view removeFromSuperview];
|
|
}];
|
|
}];
|
|
} else {
|
|
// CASE: story titles on left
|
|
[UIView animateWithDuration:0.35 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
|
self.storyNavigationController.view.frame = CGRectMake(vb.size.width,
|
|
0,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
self.storyNavigationController.view.frame.size.height);
|
|
self.dashboardViewController.view.frame = CGRectMake(self.masterWidth,
|
|
0,
|
|
vb.size.width - self.masterWidth,
|
|
vb.size.height);
|
|
} completion:^(BOOL finished) {
|
|
if (self.feedDetailIsVisible) return;
|
|
[self.storyNavigationController.view removeFromSuperview];
|
|
}];
|
|
}
|
|
|
|
if (feedDetailViewController.storiesCollection.transferredFromDashboard) {
|
|
[dashboardViewController.storiesModule.storiesCollection
|
|
transferStoriesFromCollection:feedDetailViewController.storiesCollection];
|
|
[dashboardViewController.storiesModule fadeSelectedCell];
|
|
}
|
|
}
|
|
|
|
- (void)transitionToShareView {
|
|
if (isSharingStory) {
|
|
return;
|
|
}
|
|
|
|
[self.appDelegate hidePopover];
|
|
CGRect vb = [self.view bounds];
|
|
self.isSharingStory = YES;
|
|
self.storyPageControl.traverseView.hidden = YES;
|
|
|
|
// adding shareViewController
|
|
[self.shareNavigationController removeFromParentViewController];
|
|
[self addChildViewController:self.shareNavigationController];
|
|
[self.view insertSubview:self.shareNavigationController.view
|
|
aboveSubview:self.storyNavigationController.view];
|
|
[self.shareNavigationController didMoveToParentViewController:self];
|
|
|
|
self.shareNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
vb.size.height,
|
|
self.storyPageControl.view.frame.size.width,
|
|
NB_DEFAULT_SHARE_HEIGHT);
|
|
[self.storyPageControl resizeScrollView];
|
|
|
|
self.shareViewController.view.frame = CGRectMake(0,
|
|
0,
|
|
self.shareNavigationController.view.frame.size.width,
|
|
self.shareNavigationController.view.frame.size.height - 44);
|
|
[self.shareNavigationController.view setNeedsDisplay];
|
|
[self.shareViewController.commentField becomeFirstResponder];
|
|
|
|
// if (!self.keyboardIsShown)
|
|
// [self keyboardWillShowOrHide:nil];
|
|
}
|
|
|
|
- (void)transitionFromShareView {
|
|
if (!isSharingStory) {
|
|
return;
|
|
}
|
|
|
|
[self.appDelegate hidePopover];
|
|
CGRect vb = [self.view bounds];
|
|
self.isSharingStory = NO;
|
|
self.storyPageControl.traverseView.hidden = NO;
|
|
|
|
if ([self.shareViewController.commentField isFirstResponder] && self.keyboardIsShown) {
|
|
self.isHidingStory = YES; // the flag allows the keyboard animation to also slide down the share view
|
|
[self.shareViewController.commentField resignFirstResponder];
|
|
} else {
|
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
|
if (UIInterfaceOrientationIsPortrait(orientation) && !self.storyTitlesOnLeft) {
|
|
self.storyNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
0,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
storyTitlesYCoordinate);
|
|
} else {
|
|
self.storyNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
0,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
vb.size.height);
|
|
}
|
|
|
|
[UIView animateWithDuration:NB_DEFAULT_SLIDER_INTERVAL animations:^{
|
|
self.shareNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
vb.size.height,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
NB_DEFAULT_SHARE_HEIGHT);
|
|
} completion:^(BOOL finished) {
|
|
[self.shareNavigationController.view removeFromSuperview];
|
|
}];
|
|
}
|
|
|
|
}
|
|
|
|
- (void)dragStoryToolbar:(int)yCoordinate {
|
|
|
|
CGRect vb = [self.view bounds];
|
|
// account for top toolbar and status bar
|
|
yCoordinate = yCoordinate + 64 + 20;
|
|
|
|
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
|
|
|
|
if (yCoordinate <= (vb.size.height)) {
|
|
yCoordinate = MAX(yCoordinate, 384);
|
|
self.storyTitlesYCoordinate = yCoordinate;
|
|
[userPreferences setInteger:yCoordinate forKey:@"storyTitlesYCoordinate"];
|
|
[userPreferences synchronize];
|
|
|
|
self.storyNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
0,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
yCoordinate);
|
|
if (self.storyTitlesOnLeft) {
|
|
self.storyTitlesStub.hidden = NO;
|
|
self.storyTitlesStub.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
yCoordinate,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
vb.size.height - yCoordinate);
|
|
} else {
|
|
self.feedDetailViewController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
yCoordinate,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
vb.size.height - yCoordinate);
|
|
[self.feedDetailViewController checkScroll];
|
|
}
|
|
} else if (yCoordinate >= (vb.size.height)){
|
|
[userPreferences setInteger:CGRectGetHeight(vb) forKey:@"storyTitlesYCoordinate"];
|
|
[userPreferences synchronize];
|
|
self.storyTitlesYCoordinate = CGRectGetHeight(vb);
|
|
self.storyNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
0,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
vb.size.height);
|
|
if (self.storyTitlesOnLeft) {
|
|
self.storyTitlesStub.hidden = NO;
|
|
self.storyTitlesStub.frame = CGRectMake(self.feedDetailViewController.view.frame.origin.x,
|
|
0,
|
|
self.feedDetailViewController.view.frame.size.width,
|
|
0);
|
|
}
|
|
}
|
|
|
|
UITableView *stories = appDelegate.feedDetailViewController.storyTitlesTable;
|
|
NSInteger location = appDelegate.storiesCollection.locationOfActiveStory;
|
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:location inSection:0];
|
|
NSArray *visible = [stories visibleCells];
|
|
for (UITableViewCell *cell in visible) {
|
|
if ([stories indexPathForCell:cell].row == indexPath.row) {
|
|
indexPath = nil;
|
|
break;
|
|
}
|
|
}
|
|
if (indexPath && location >= 0) {
|
|
[stories selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];
|
|
}
|
|
|
|
[appDelegate.feedDetailViewController.notifier setNeedsLayout];
|
|
|
|
}
|
|
|
|
- (bool)isHardwareKeyboardUsed:(NSNotification*)keyboardNotification {
|
|
NSDictionary* info = [keyboardNotification userInfo];
|
|
CGRect keyboardEndFrame;
|
|
[[info valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
|
|
float height = [[UIScreen mainScreen] bounds].size.height - keyboardEndFrame.origin.y;
|
|
float gThresholdForHardwareKeyboardToolbar = 160.f;
|
|
return height < gThresholdForHardwareKeyboardToolbar;
|
|
}
|
|
|
|
-(void)keyboardWillShowOrHide:(NSNotification*)notification {
|
|
if (notification.name == UIKeyboardWillShowNotification) {
|
|
self.keyboardIsShown = YES;
|
|
} else if (notification.name == UIKeyboardWillHideNotification) {
|
|
self.keyboardIsShown = NO;
|
|
}
|
|
|
|
if (self.keyboardIsShown && !self.isSharingStory) {
|
|
return;
|
|
}
|
|
|
|
NSDictionary *userInfo = notification.userInfo;
|
|
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
|
|
UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
|
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
|
CGRect vb = [self.view bounds];
|
|
CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
|
CGRect storyNavigationFrame = self.storyNavigationController.view.frame;
|
|
|
|
if ([self isHardwareKeyboardUsed:notification] && self.keyboardIsShown) {
|
|
CGFloat keyboardHeight = [[[self view] window] frame].size.height - keyboardFrame.origin.y;
|
|
keyboardFrame.size.height = keyboardHeight;
|
|
}
|
|
|
|
self.shareNavigationController.view.frame = CGRectMake(storyNavigationFrame.origin.x,
|
|
vb.size.height,
|
|
storyNavigationFrame.size.width,
|
|
NB_DEFAULT_SHARE_HEIGHT);
|
|
CGRect shareViewFrame = self.shareNavigationController.view.frame;
|
|
|
|
if (self.keyboardIsShown && self.isSharingStory) {
|
|
if (UIInterfaceOrientationIsPortrait(orientation)) {
|
|
storyNavigationFrame.size.height = vb.size.height - NB_DEFAULT_SHARE_HEIGHT - keyboardFrame.size.height + 44;
|
|
shareViewFrame.origin.y = vb.size.height - NB_DEFAULT_SHARE_HEIGHT - keyboardFrame.size.height;
|
|
} else {
|
|
storyNavigationFrame.size.height = vb.size.height - NB_DEFAULT_SHARE_HEIGHT - keyboardFrame.size.height + 44;
|
|
shareViewFrame.origin.y = vb.size.height - NB_DEFAULT_SHARE_HEIGHT - keyboardFrame.size.height;
|
|
}
|
|
} else if (self.isSharingStory) {
|
|
if (UIInterfaceOrientationIsPortrait(orientation)) {
|
|
storyNavigationFrame.size.height = vb.size.height - NB_DEFAULT_SHARE_HEIGHT + 64;
|
|
shareViewFrame.origin.y = vb.size.height - NB_DEFAULT_SHARE_HEIGHT;
|
|
} else {
|
|
storyNavigationFrame.size.height = vb.size.height - NB_DEFAULT_SHARE_HEIGHT + 64;
|
|
shareViewFrame.origin.y = vb.size.height - NB_DEFAULT_SHARE_HEIGHT;
|
|
}
|
|
}
|
|
|
|
// CASE: when dismissing the keyboard but not dismissing the share view
|
|
if (!self.keyboardIsShown && !self.isHidingStory) {
|
|
self.storyNavigationController.view.frame = storyNavigationFrame;
|
|
// CASE: when dismissing the keyboard AND dismissing the share view
|
|
} else if (!self.keyboardIsShown && self.isHidingStory) {
|
|
if (UIInterfaceOrientationIsPortrait(orientation) && !self.storyTitlesOnLeft) {
|
|
self.storyNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
0,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
vb.size.height);
|
|
} else {
|
|
self.storyNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
0,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
vb.size.height);
|
|
}
|
|
}
|
|
|
|
int newStoryNavigationFrameHeight = vb.size.height - NB_DEFAULT_SHARE_HEIGHT - keyboardFrame.size.height + 44;
|
|
|
|
|
|
[UIView animateWithDuration:duration
|
|
delay:0
|
|
options:UIViewAnimationOptionBeginFromCurrentState | curve
|
|
animations:^{
|
|
if (self.isHidingStory) {
|
|
self.shareNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
vb.size.height,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
NB_DEFAULT_SHARE_HEIGHT);
|
|
if (UIInterfaceOrientationIsPortrait(orientation) && !self.storyTitlesOnLeft) {
|
|
self.storyNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
0,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
storyTitlesYCoordinate);
|
|
} else {
|
|
self.storyNavigationController.view.frame = CGRectMake(self.storyNavigationController.view.frame.origin.x,
|
|
0,
|
|
self.storyNavigationController.view.frame.size.width,
|
|
vb.size.height);
|
|
}
|
|
} else {
|
|
self.shareNavigationController.view.frame = shareViewFrame;
|
|
// if the toolbar is higher, animate
|
|
if (UIInterfaceOrientationIsPortrait(orientation) && !self.storyTitlesOnLeft) {
|
|
if (self.storyNavigationController.view.frame.size.height < newStoryNavigationFrameHeight) {
|
|
self.storyNavigationController.view.frame = storyNavigationFrame;
|
|
}
|
|
}
|
|
}
|
|
|
|
} completion:^(BOOL finished) {
|
|
if (self.keyboardIsShown) {
|
|
self.storyNavigationController.view.frame = storyNavigationFrame;
|
|
[self.storyPageControl.currentPage scrolltoComment];
|
|
[self.storyPageControl resizeScrollView];
|
|
} else {
|
|
// remove the shareNavigationController after keyboard slides down
|
|
if (self.isHidingStory) {
|
|
self.isHidingStory = NO;
|
|
[self.shareNavigationController.view removeFromSuperview];
|
|
}
|
|
}
|
|
}];
|
|
}
|
|
|
|
@end
|