Last active
August 29, 2015 14:22
-
-
Save alexrainman/df03bd8d03a21783237d to your computer and use it in GitHub Desktop.
Dynamic UIViewPageController for Xamarin iOS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UIKit; | |
using System.Collections.Generic; | |
using CoreGraphics; | |
// ported from https://github.com/nsobadzhiev/DynamicPageViewController/blob/master/DynamicPageViewController/DMDynamicViewController.swift | |
namespace YourNamespace | |
{ | |
/*protocol DMDynamicPageViewControllerDelegate { | |
func pageViewController(pageController: DMDynamicViewController, didSwitchToViewController viewController: UIViewController) | |
func pageViewController(pageController: DMDynamicViewController, didChangeViewControllers viewControllers: Array<UIViewController>) | |
}*/ | |
public class DPageViewController: UIViewController, IUIScrollViewDelegate { | |
/*var delegate: DMDynamicPageViewControllerDelegate? = nil | |
func notifyDelegateDidSwitchPage() { | |
self.delegate?.pageViewController(self, didSwitchToViewController: self.viewControllers![self.currentPage]) | |
} | |
func notifyDelegateDidChangeControllers() { | |
self.delegate?.pageViewController(self, didChangeViewControllers: self.viewControllers!) | |
}*/ | |
UIScrollView containerScrollView; | |
nfloat pageWidth = 1f; | |
public List<UIViewController> ViewControllers; | |
int _currentPage; | |
public int CurrentPage { | |
get { return _currentPage; } | |
set { | |
_currentPage = value; | |
if (_currentPage >= ViewControllers.Count) | |
{ | |
_currentPage = ViewControllers.Count - 1; | |
} | |
containerScrollView.Delegate = null; | |
containerScrollView.ContentOffset = new CGPoint ((nfloat)_currentPage * View.Bounds.Size.Width, 0.0); | |
containerScrollView.Delegate = this; | |
// Set the fully switched page in order to notify the delegates about it if needed. | |
FullySwitchedPage = CurrentPage; | |
} | |
} | |
int _fullySwitchedPage; | |
public int FullySwitchedPage { | |
get { return _fullySwitchedPage; } | |
set { | |
if (value != _fullySwitchedPage) { | |
// The page is fully switched. | |
if (_fullySwitchedPage < ViewControllers.Count) { | |
var previousViewController = ViewControllers[_fullySwitchedPage]; | |
// Perform the "disappear" sequence of methods manually when the view of | |
// the controller is not visible at all. | |
previousViewController.WillMoveToParentViewController(this); | |
previousViewController.ViewWillDisappear (false); | |
previousViewController.ViewDidDisappear (false); | |
previousViewController.DidMoveToParentViewController (this); | |
previousViewController.WillMoveToParentViewController (this); | |
previousViewController.ViewWillAppear (false); | |
previousViewController.ViewDidAppear (false); | |
previousViewController.DidMoveToParentViewController (this); | |
} | |
} | |
_fullySwitchedPage = value; | |
} | |
} | |
public DPageViewController(List<UIViewController> viewControllers) { | |
//super.init(nibName: nil, bundle: nil) | |
ViewControllers = viewControllers; | |
//self.notifyDelegateDidChangeControllers() | |
} | |
/*init(viewControllers: Array<UIViewController>) { | |
super.init(nibName: nil, bundle: nil) | |
self.viewControllers = viewControllers | |
self.notifyDelegateDidChangeControllers() | |
} | |
required override init(nibName nibN ameOrNil: String!, bundle nibBundleOrNil: NSBundle!) { | |
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) | |
} | |
required init(coder: NSCoder) { | |
super.init(coder: coder) | |
}*/ | |
public override void ViewDidLoad() { | |
base.ViewDidLoad (); | |
containerScrollView = new UIScrollView (new CGRect(0, 44, View.Frame.Size.Width, View.Frame.Size.Height - 90)); //frame: self.view.bounds | |
containerScrollView.PagingEnabled = true; | |
containerScrollView.AlwaysBounceVertical = false; | |
containerScrollView.AlwaysBounceHorizontal = true; // drag with only one view controller | |
containerScrollView.ShowsHorizontalScrollIndicator = false; | |
containerScrollView.Delegate = this; | |
pageWidth = View.Frame.Size.Width; | |
View.AddSubview(containerScrollView); | |
LayoutPages(); | |
} | |
public override void ViewDidLayoutSubviews() { | |
for (var i = 0; i < ViewControllers.Count; i += 1) { | |
var pageX = (nfloat)i * View.Bounds.Size.Width; | |
ViewControllers [i].View.Frame = new CGRect (pageX, 0.0, View.Bounds.Size.Width, View.Bounds.Size.Height); | |
} | |
// It is important to set the pageWidth property before the contentSize and contentOffset, | |
// in order to use the new width into scrollView delegate methods. | |
pageWidth = View.Bounds.Size.Width; | |
containerScrollView.ContentSize = new CGSize ((nfloat)ViewControllers.Count * View.Bounds.Size.Width, 1.0); | |
containerScrollView.ContentOffset = new CGPoint ((nfloat)CurrentPage * View.Bounds.Size.Width, 0.0); | |
} | |
public override void DidReceiveMemoryWarning() { | |
base.DidReceiveMemoryWarning (); | |
// Dispose of any resources that can be recreated. | |
} | |
void LayoutPages() { | |
foreach(var pageView in containerScrollView.Subviews) { | |
pageView.RemoveFromSuperview(); | |
} | |
for (var i = 0; i < ViewControllers.Count; i++) { | |
var page = ViewControllers [i]; | |
AddChildViewController(page); | |
var nextFrame = new CGRect ((nfloat)i * View.Bounds.Size.Width, View.Frame.Y, View.Frame.Size.Width, View.Frame.Size.Height); // Origin.Y | |
page.View.Frame = nextFrame; | |
containerScrollView.AddSubview (page.View); | |
page.DidMoveToParentViewController (this); | |
} | |
containerScrollView.ContentSize = new CGSize(View.Bounds.Size.Width * (nfloat)ViewControllers.Count, 1.0); | |
} | |
void WillMoveToParentViewController() { | |
var page = (int)((containerScrollView.ContentOffset.X - pageWidth / 2.0) / pageWidth) + 1; | |
if (CurrentPage != page) | |
{ | |
CurrentPage = page; | |
//FullySwitchedPage = page; | |
} | |
} | |
public void InsertPage(UIViewController viewController, int index) { | |
ViewControllers.Insert(index, viewController); | |
LayoutPages(); | |
CurrentPage = index; | |
//self.notifyDelegateDidChangeControllers() | |
} | |
public void RemovePage(UIViewController viewController) { | |
for (var i = 0; i < ViewControllers.Count; i += 1) { | |
if (ViewControllers[i] == viewController) { | |
ViewControllers.RemoveAt (i); | |
LayoutPages(); | |
//self.notifyDelegateDidChangeControllers() | |
} | |
} | |
} | |
// MARK: UIScrollViewDelegate | |
[Foundation.Export ("scrollViewDidScroll:")] | |
public void Scrolled (UIScrollView scrollView) | |
{ | |
// Update the page when more than 50% of the previous/next page is visible | |
var page = Math.Floor((containerScrollView.ContentOffset.X - pageWidth / 2) / pageWidth) + 1; | |
/*if (CurrentPage != (int)page) { | |
// Check the page to avoid "index out of bounds" exception. | |
if (page >= 0 && (int)page < ViewControllers.Count) | |
{ | |
//self.notifyDelegateDidSwitchPage() | |
} | |
}*/ | |
// Check whether the current view controller is fully presented. | |
if ((int)containerScrollView.ContentOffset.X % (int)pageWidth == 0) | |
{ | |
CurrentPage = (int)page; | |
//FullySwitchedPage = CurrentPage; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment