// _____ _ // |_ _| |_ _ _ ___ ___ _ __ __ _ // | | | ' \| '_/ -_) -_) ' \/ _` |_ // |_| |_||_|_| \___\___|_|_|_\__,_(_) // // Threema iOS Client // Copyright (c) 2015-2020 Threema GmbH // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License, version 3, // as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #import "ParallaxPageViewController.h" #import "PageContentViewController.h" #import "PageView.h" #import "RectUtil.h" #import "UIImage+ColoredImage.h" #import "AppDelegate.h" @interface ParallaxPageViewController () @property PageView *pageContainerView; @property NSInteger index; @end @implementation ParallaxPageViewController @synthesize parallaxFactor = _parallaxFactor; - (void)viewDidLoad { [super viewDidLoad]; [self setup]; [self updateNavigationButtons]; [self updatePageControl]; _pageContainerView.backgroundColor = [UIColor clearColor]; [self setNeedsStatusBarAppearanceUpdate]; } - (BOOL)prefersStatusBarHidden { return YES; } - (BOOL)shouldAutorotate { return NO; } -(UIInterfaceOrientationMask)supportedInterfaceOrientations { if (SYSTEM_IS_IPAD) { return UIInterfaceOrientationMaskAll; } else { return UIInterfaceOrientationMaskPortrait; } } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; _pageContainerView.bgView = _bgView; } - (void)setViewControllers:(NSArray *)viewControllers { _viewControllers = viewControllers; // setup parent child relationship for (PageContentViewController *vc in _viewControllers) { vc.containerDelegate = self; [self addChildViewController:vc]; [vc didMoveToParentViewController:self]; } } - (void)setup { _pageContainerView = [[PageView alloc] initWithFrame:self.view.frame]; _pageContainerView.delegate = self; _pageContainerView.datasource = self; if (_parallaxFactor) { _pageContainerView.parallaxFactor = _parallaxFactor.floatValue; } [self.view addSubview:_pageContainerView]; [self.view bringSubviewToFront:_controlsView]; [_pageLeftButton setImage:[UIImage imageNamed:@"ArrowPrevious" inColor:[Colors mainThemeDark]] forState:UIControlStateNormal]; [_pageRightButton setImage:[UIImage imageNamed:@"ArrowNext" inColor:[Colors mainThemeDark]] forState:UIControlStateNormal]; _pageLeftButton.accessibilityLabel = [BundleUtil localizedStringForKey:@"previous"]; _pageRightButton.accessibilityLabel = [BundleUtil localizedStringForKey:@"next"]; _pageControl.accessibilityLabel = [NSString stringWithFormat:@"%li %@ %li", (long)_pageControl.currentPage + 1, [BundleUtil localizedStringForKey:@"from"], (long)_pageControl.numberOfPages]; _index = 0; if ([AppDelegate hasBottomSafeAreaInsets]) { _controlsView.frame = CGRectMake(_controlsView.frame.origin.x, _controlsView.frame.origin.y - 20.0, _controlsView.frame.size.width, _controlsView.frame.size.height + 20.0); } } - (void)setParallaxFactor:(NSNumber *)parallaxFactor { _parallaxFactor = parallaxFactor; _pageContainerView.parallaxFactor = parallaxFactor.floatValue; } - (NSNumber *)parallaxFactor { return [NSNumber numberWithFloat:_pageContainerView.parallaxFactor]; } - (NSInteger)nextIndexForIncrement:(NSInteger)increment { return _index + increment; } - (UIView *)viewAtIndex:(NSInteger)index { UIViewController *viewController = (UIViewController *)_viewControllers[index]; return viewController.view; } - (void)updateNavigationButtons { if (_index == 0) { _pageLeftButton.hidden = YES; } else { _pageLeftButton.hidden = NO; } if (_index == _viewControllers.count - 1) { _pageRightButton.hidden = YES; } else { _pageRightButton.hidden = NO; } } - (void)updatePageControl { _pageControl.currentPage = _index; _pageControl.numberOfPages = _viewControllers.count; } #pragma mark - PageViewDataSource - (UIView *) currentView: (CGRect) frame { return [self viewAtIndex:_index]; } - (UIView *) nextView: (CGRect) frame { if (_index == _viewControllers.count - 1) { return nil; } NSInteger nextIndex = [self nextIndexForIncrement:1]; return [self viewAtIndex:nextIndex]; } - (UIView *) previousView: (CGRect) frame { if (_index == 0) { return nil; } NSInteger previousIndex = [self nextIndexForIncrement:-1]; return [self viewAtIndex:previousIndex]; } - (BOOL) moveToNext { if (_index == _viewControllers.count - 1) { return NO; } if ([self canMoveFromCurrentViewController]) { return NO; } _index++; _pageControl.accessibilityLabel = [NSString stringWithFormat:@"%li %@ %li", _index + 1, [BundleUtil localizedStringForKey:@"from"], (long)_pageControl.numberOfPages]; return YES; } - (BOOL) moveToPrevious { if (_index == 0) { return NO; } _index--; _pageControl.accessibilityLabel = [NSString stringWithFormat:@"%li %@ %li", _index + 1, [BundleUtil localizedStringForKey:@"from"], (long)_pageControl.numberOfPages]; return YES; } - (BOOL)canMoveFromCurrentViewController { PageContentViewController *currentVc = _viewControllers[_index]; if ([currentVc respondsToSelector:@selector(isInputValid)]) { return [currentVc isInputValid] == NO; } else { return YES; } } - (UIViewController *)viewControllerForView:(UIView *)view { for (UIViewController *vc in _viewControllers) { if (vc.view == view) { return vc; } } return nil; } #pragma mark - PageViewDelegate - (void) willPageFrom: (UIView *) fromView toView: (UIView *) toView { UIViewController *toVc = [self viewControllerForView:toView]; [toVc beginAppearanceTransition:YES animated:YES]; UIViewController *fromVc = [self viewControllerForView:fromView]; [fromVc beginAppearanceTransition:NO animated:YES]; } - (void) didPageFrom: (UIView *) fromView toView: (UIView *) toView { UIViewController *toVc = [self viewControllerForView:toView]; [toVc endAppearanceTransition]; UIViewController *fromVc = [self viewControllerForView:fromView]; [fromVc endAppearanceTransition]; [self updateNavigationButtons]; [self updatePageControl]; } #pragma mark - actions - (IBAction)pageLeftAction:(id)sender { [_pageContainerView pageLeft]; } - (IBAction)pageRightAction:(id)sender { [_pageContainerView pageRight]; } - (IBAction)pageControlChanged:(id)sender { UIPageControl *pc = (UIPageControl *)sender; if (_index < pc.currentPage) { [_pageContainerView pageLeft]; } else { [_pageContainerView pageRight]; } } #pragma mark - PageContentControllerDelegate - (void)hideControls:(BOOL)hideControls { CGFloat yOffset; if (hideControls) { yOffset = CGRectGetMaxY(self.view.frame); } else { yOffset = CGRectGetMaxY(self.view.frame) - CGRectGetHeight(_controlsView.frame); } CGRect rect = [RectUtil setYPositionOf:_controlsView.frame y:yOffset]; _controlsView.frame = rect; [_pageContainerView enablePanGesture:(hideControls == NO)]; } - (void)pageRight { [_pageContainerView pageRight]; } - (void)pageLeft { [_pageContainerView pageLeft]; } @end