diff --git a/.gitignore b/.gitignore index 582ef026..21f213ff 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,6 @@ Kiip/binding/libKiip.a /FlurryAnalytics/binding/libFlurry.a CorePlot/binding/CorePlot_0.9/ - -*.a +*.a +build +xcuserdata \ No newline at end of file diff --git a/iCarousel/binding/ApiDefinition.cs b/iCarousel/binding/ApiDefinition.cs index 1bd2f33e..898c4219 100644 --- a/iCarousel/binding/ApiDefinition.cs +++ b/iCarousel/binding/ApiDefinition.cs @@ -1,17 +1,15 @@ using System; -using System.Drawing; - -using MonoTouch.ObjCRuntime; -using MonoTouch.Foundation; -using MonoTouch.UIKit; -using MonoTouch.CoreAnimation; +using CoreAnimation; +using CoreGraphics; +using Foundation; +using ObjCRuntime; +using UIKit; namespace iCarouselSDK { - [BaseType (typeof (UIView))] - interface iCarousel { - + interface iCarousel + { [Export ("dataSource", ArgumentSemantic.Assign)][NullAllowed] NSObject WeakDataSource { get; set; } @@ -28,16 +26,16 @@ interface iCarousel { iCarouselType CarouselType { get; set; } [Export ("perspective", ArgumentSemantic.Assign)] - float Perspective { get; set; } + nfloat Perspective { get; set; } [Export ("decelerationRate", ArgumentSemantic.Assign)] - float DecelerationRate { get; set; } + nfloat DecelerationRate { get; set; } [Export ("scrollSpeed", ArgumentSemantic.Assign)] - float ScrollSpeed { get; set; } + nfloat ScrollSpeed { get; set; } [Export ("bounceDistance", ArgumentSemantic.Assign)] - float BounceDistance { get; set; } + nfloat BounceDistance { get; set; } [Export ("scrollEnabled", ArgumentSemantic.Assign)] bool ScrollEnabled { [Bind ("isScrollEnabled")] get; set; } @@ -52,25 +50,25 @@ interface iCarousel { bool Bounces { get; set; } [Export ("scrollOffset", ArgumentSemantic.Assign)] - float ScrollOffset { get; set; } + nfloat ScrollOffset { get; set; } [Export ("offsetMultiplier")] - float OffsetMultiplier { get; } + nfloat OffsetMultiplier { get; } [Export ("contentOffset", ArgumentSemantic.Assign)] - SizeF ContentOffset { get; set; } + CGSize ContentOffset { get; set; } [Export ("viewpointOffset", ArgumentSemantic.Assign)] - SizeF ViewpointOffset { get; set; } + CGSize ViewpointOffset { get; set; } [Export ("numberOfItems")] - int NumberOfItems { get; } + nint NumberOfItems { get; } [Export ("numberOfPlaceholders")] - int NumberOfPlaceholders { get; } + nint NumberOfPlaceholders { get; } [Export ("currentItemIndex", ArgumentSemantic.Assign)] - int CurrentItemIndex { get; set; } + nint CurrentItemIndex { get; set; } [Export ("currentItemView")] UIView CurrentItemView { get; } @@ -79,16 +77,16 @@ interface iCarousel { NSNumber [] IndexesForVisibleItems { get; } [Export ("numberOfVisibleItems")] - int NumberOfVisibleItems { get; } + nint NumberOfVisibleItems { get; } [Export ("itemWidth")] - float ItemWidth { get; } + nfloat ItemWidth { get; } [Export ("contentView")] UIView ContentView { get; } [Export ("toggle")] - float Toggle { get; } + nfloat Toggle { get; } [Export ("stopAtItemBoundary", ArgumentSemantic.Assign)] bool StopAtItemBoundary { get; set; } @@ -112,46 +110,46 @@ interface iCarousel { bool Scrolling { [Bind ("isScrolling")] get; set; } [Export ("scrollByOffset:duration:")] - void ScrollByOffset (float offset, double duration); + void ScrollByOffset (nfloat offset, double duration); [Export ("scrollToOffset:duration:")] - void ScrollToOffset (float offset, double duration); + void ScrollToOffset (nfloat offset, double duration); [Export ("scrollByNumberOfItems:duration:")] - void ScrollByNumberOfItems (int itemCount, double duration); + void ScrollByNumberOfItems (nint itemCount, double duration); [Export ("scrollToItemAtIndex:duration:")] - void ScrollToItem (int index, double duration); + void ScrollToItem (nint index, double duration); [Export ("scrollToItemAtIndex:animated:")] - void ScrollToItem (int index, bool animated); + void ScrollToItem (nint index, bool animated); [Export ("itemViewAtIndex:")] - UIView GetItemView (int index); + UIView GetItemView (nint index); [Export ("indexOfItemView:")] - int IndexOfItemView (UIView view); + nint IndexOfItemView (UIView view); [Export ("indexOfItemViewOrSubview:")] - int IndexOfItemViewOrSubview (UIView view); + nint IndexOfItemViewOrSubview (UIView view); [Export ("offsetForItemAtIndex:")] - float OffsetForItem (int index); - + nfloat OffsetForItem (nint index); + [Export ("removeItemAtIndex:animated:")] - void RemoveItem (int index, bool animated); + void RemoveItem (nint index, bool animated); [Export ("insertItemAtIndex:animated:")] - void InsertItem (int index, bool animated); + void InsertItem (nint index, bool animated); [Export ("reloadItemAtIndex:animated:")] - void ReloadItem (int index, bool animated); + void ReloadItem (nint index, bool animated); [Export ("reloadData")] void ReloadData (); [Export ("initWithFrame:")] - IntPtr Constructor (RectangleF frame); + IntPtr Constructor (CGRect frame); } [BaseType (typeof (NSObject))] @@ -160,16 +158,16 @@ interface iCarousel { interface iCarouselDataSource { [Export ("numberOfItemsInCarousel:")] [Abstract] - uint NumberOfItems (iCarousel carousel); + nuint NumberOfItems (iCarousel carousel); [Export ("carousel:viewForItemAtIndex:reusingView:")] [Abstract] - UIView ViewForItem (iCarousel carousel, uint index, UIView reusingView); + UIView ViewForItem (iCarousel carousel, nuint index, UIView reusingView); [Export ("numberOfPlaceholdersInCarousel:")] - uint NumberOfPlaceholders (iCarousel carousel); + nuint NumberOfPlaceholders (iCarousel carousel); [Export ("carousel:placeholderViewAtIndex:reusingView:")] - UIView PlaceholderViewAtIndex (iCarousel carousel, uint index, UIView reusingView); + UIView PlaceholderViewAtIndex (iCarousel carousel, nuint index, UIView reusingView); } [BaseType (typeof (NSObject))] @@ -202,19 +200,18 @@ interface iCarouselDelegate { void DidEndDecelerating (iCarousel carousel); [Export ("carousel:shouldSelectItemAtIndex:")] - bool ShouldSelectItem (iCarousel carousel, int index); + bool ShouldSelectItem (iCarousel carousel, nint index); [Export ("carousel:didSelectItemAtIndex:")] - void DidSelectItem (iCarousel carousel, int index); + void DidSelectItem (iCarousel carousel, nint index); [Export ("carouselItemWidth:")] - float ItemWidth (iCarousel carousel); + nfloat ItemWidth (iCarousel carousel); [Export ("carousel:itemTransformForOffset:baseTransform:")] - CATransform3D ItemTransform (iCarousel carousel, float offset, CATransform3D baseTransform); + CATransform3D ItemTransform (iCarousel carousel, nfloat offset, CATransform3D baseTransform); [Export ("carousel:valueForOption:withDefault:")] - float ValueForOption (iCarousel carousel, iCarouselOption option, float aValue); + nfloat ValueForOption (iCarousel carousel, iCarouselOption option, nfloat aValue); } -} - +} \ No newline at end of file diff --git a/iCarousel/binding/Properties/AssemblyInfo.cs b/iCarousel/binding/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..f196581e --- /dev/null +++ b/iCarousel/binding/Properties/AssemblyInfo.cs @@ -0,0 +1,17 @@ +// +// Author: +// Nicolas VERINAUD +// +// Copyright (c) 2015 Nicolas Verinaud. All Rights Reserved. +// +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("iCarouselSDK")] +[assembly: AssemblyDescription("Mono port of iCarousel library https://github.com/nicklockwood/iCarousel")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyVersion("1.8.1")] \ No newline at end of file diff --git a/iCarousel/binding/StructsAndEnums.cs b/iCarousel/binding/StructsAndEnums.cs index be32527b..c172f21c 100644 --- a/iCarousel/binding/StructsAndEnums.cs +++ b/iCarousel/binding/StructsAndEnums.cs @@ -34,5 +34,4 @@ public enum iCarouselOption FadeMax, FadeRange } -} - +} \ No newline at end of file diff --git a/iCarousel/binding/iCarouselSDK.csproj b/iCarousel/binding/iCarouselSDK.csproj index b1ab0113..bcb66ab5 100644 --- a/iCarousel/binding/iCarouselSDK.csproj +++ b/iCarousel/binding/iCarouselSDK.csproj @@ -3,14 +3,17 @@ Debug AnyCPU - 10.0.0 + 8.0.30703 2.0 {7FCFB195-20C9-41D2-99FC-B6CA70BF256D} - {F5B4F3BC-B597-4E2B-B552-EF5D8A32436F};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + {8FFB629D-F513-41CE-95D2-7ECE97B6EEEC};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Library iCarouselSDK Resources iCarouselSDK + 1.8.1 + Xamarin.iOS + v1.0 True @@ -34,7 +37,7 @@ - + @@ -46,6 +49,7 @@ + @@ -53,5 +57,6 @@ libiCarousel.a + \ No newline at end of file diff --git a/iCarousel/binding/iCarouselSDK.sln b/iCarousel/binding/iCarouselSDK.sln new file mode 100644 index 00000000..6905e5d4 --- /dev/null +++ b/iCarousel/binding/iCarouselSDK.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iCarouselSDK", "iCarouselSDK.csproj", "{7FCFB195-20C9-41D2-99FC-B6CA70BF256D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7FCFB195-20C9-41D2-99FC-B6CA70BF256D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7FCFB195-20C9-41D2-99FC-B6CA70BF256D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7FCFB195-20C9-41D2-99FC-B6CA70BF256D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7FCFB195-20C9-41D2-99FC-B6CA70BF256D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + version = 1.8.1 + EndGlobalSection +EndGlobal diff --git a/iCarousel/binding/libiCarousel.a b/iCarousel/binding/libiCarousel.a index 8f6e2a31..45bc3935 100644 Binary files a/iCarousel/binding/libiCarousel.a and b/iCarousel/binding/libiCarousel.a differ diff --git a/iCarousel/binding/libiCarousel.linkwith.cs b/iCarousel/binding/libiCarousel.linkwith.cs index 904db855..91a740b9 100644 --- a/iCarousel/binding/libiCarousel.linkwith.cs +++ b/iCarousel/binding/libiCarousel.linkwith.cs @@ -1,4 +1,4 @@ using System; -using MonoTouch.ObjCRuntime; +using ObjCRuntime; -[assembly: LinkWith ("libiCarousel.a", LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Simulator, Frameworks = "QuartzCore CoreGraphics", ForceLoad = true)] +[assembly: LinkWith ("libiCarousel.a", LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Arm64 | LinkTarget.Simulator, Frameworks = "QuartzCore CoreGraphics", ForceLoad = true)] diff --git a/iCarousel/docs/ApiDefinition/Messaging.xml b/iCarousel/docs/ApiDefinition/Messaging.xml index 2af8ceb3..dfa9f426 100644 --- a/iCarousel/docs/ApiDefinition/Messaging.xml +++ b/iCarousel/docs/ApiDefinition/Messaging.xml @@ -27,6 +27,102 @@ To be added. + + + + Method + + 0.0.0.0 + + + System.Boolean + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Boolean + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Boolean + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Boolean + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + @@ -85,6 +181,76 @@ To be added. + + + + Method + + 0.0.0.0 + + + System.Single + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Single + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Single + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + @@ -113,6 +279,76 @@ To be added. + + + + Method + + 0.0.0.0 + + + System.Single + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Single + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Single + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + @@ -141,39 +377,37 @@ To be added. - - - + + + Method 0.0.0.0 - System.UInt32 + System.Int32 - To be added. To be added. - To be added. To be added. To be added. To be added. - - - + + + Method 0.0.0.0 - System.UInt32 + System.Int32 @@ -189,52 +423,952 @@ To be added. - - - + + + Method 0.0.0.0 - System.Void + System.Int32 - - To be added. To be added. - To be added. - To be added. To be added. + To be added. To be added. - - - + + + Method 0.0.0.0 - System.Void + System.Int32 - - + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.IntPtr + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.IntPtr + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.IntPtr + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.IntPtr + + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.IntPtr + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.IntPtr + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.IntPtr + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.IntPtr + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.IntPtr + + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.IntPtr + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Drawing.SizeF + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Drawing.SizeF + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.UInt32 + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.UInt32 + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + To be added. To be added. To be added. - To be added. To be added. To be added. diff --git a/iCarousel/docs/iCarouselSDK/IiCarouselDataSource.xml b/iCarousel/docs/iCarouselSDK/IiCarouselDataSource.xml new file mode 100644 index 00000000..0f887726 --- /dev/null +++ b/iCarousel/docs/iCarouselSDK/IiCarouselDataSource.xml @@ -0,0 +1,87 @@ + + + + + iCarouselSDK + 0.0.0.0 + + + + MonoTouch.ObjCRuntime.INativeObject + + + System.IDisposable + + + + + MonoTouch.Foundation.Protocol(Name="iCarouselDataSource", WrapperType=typeof(iCarouselSDK.iCarouselDataSourceWrapper)) + + + + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + + MonoTouch.Foundation.Export("numberOfItemsInCarousel:") + + + MonoTouch.Foundation.Preserve(Conditional=true) + + + + System.UInt32 + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + + MonoTouch.Foundation.Export("carousel:viewForItemAtIndex:reusingView:") + + + MonoTouch.Foundation.Preserve(Conditional=true) + + + + MonoTouch.UIKit.UIView + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + diff --git a/iCarousel/docs/iCarouselSDK/IiCarouselDelegate.xml b/iCarousel/docs/iCarouselSDK/IiCarouselDelegate.xml new file mode 100644 index 00000000..c5112466 --- /dev/null +++ b/iCarousel/docs/iCarouselSDK/IiCarouselDelegate.xml @@ -0,0 +1,26 @@ + + + + + iCarouselSDK + 0.0.0.0 + + + + MonoTouch.ObjCRuntime.INativeObject + + + System.IDisposable + + + + + MonoTouch.Foundation.Protocol(Name="iCarouselDelegate", WrapperType=typeof(iCarouselSDK.iCarouselDelegateWrapper)) + + + + To be added. + To be added. + + + diff --git a/iCarousel/docs/iCarouselSDK/iCarousel.xml b/iCarousel/docs/iCarouselSDK/iCarousel.xml index 92687dd0..9e1580dd 100644 --- a/iCarousel/docs/iCarouselSDK/iCarousel.xml +++ b/iCarousel/docs/iCarouselSDK/iCarousel.xml @@ -136,10 +136,10 @@ - get: MonoTouch.Foundation.Export("bounceDistance", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("bounceDistance", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setBounceDistance:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setBounceDistance:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -160,10 +160,10 @@ - get: MonoTouch.Foundation.Export("bounces", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("bounces", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setBounces:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setBounces:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -184,10 +184,10 @@ - get: MonoTouch.Foundation.Export("type", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("type", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setType:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setType:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -208,10 +208,10 @@ - get: MonoTouch.Foundation.Export("centerItemWhenSelected", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("centerItemWhenSelected", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setCenterItemWhenSelected:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setCenterItemWhenSelected:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -248,10 +248,10 @@ - get: MonoTouch.Foundation.Export("contentOffset", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("contentOffset", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setContentOffset:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setContentOffset:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -293,10 +293,10 @@ - get: MonoTouch.Foundation.Export("currentItemIndex", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("currentItemIndex", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setCurrentItemIndex:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setCurrentItemIndex:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -378,10 +378,10 @@ - get: MonoTouch.Foundation.Export("decelerationRate", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("decelerationRate", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setDecelerationRate:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setDecelerationRate:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -486,10 +486,10 @@ - get: MonoTouch.Foundation.Export("ignorePerpendicularSwipes", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("ignorePerpendicularSwipes", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setIgnorePerpendicularSwipes:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setIgnorePerpendicularSwipes:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -737,10 +737,10 @@ - get: MonoTouch.Foundation.Export("perspective", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("perspective", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setPerspective:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setPerspective:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -886,10 +886,10 @@ - get: MonoTouch.Foundation.Export("isScrollEnabled", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("isScrollEnabled", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setScrollEnabled:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setScrollEnabled:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -934,10 +934,10 @@ - get: MonoTouch.Foundation.Export("scrollOffset", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("scrollOffset", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setScrollOffset:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setScrollOffset:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -958,10 +958,10 @@ - get: MonoTouch.Foundation.Export("scrollSpeed", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("scrollSpeed", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setScrollSpeed:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setScrollSpeed:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -1034,10 +1034,10 @@ - get: MonoTouch.Foundation.Export("scrollToItemBoundary", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("scrollToItemBoundary", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setScrollToItemBoundary:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setScrollToItemBoundary:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -1084,10 +1084,10 @@ - get: MonoTouch.Foundation.Export("stopAtItemBoundary", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("stopAtItemBoundary", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setStopAtItemBoundary:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setStopAtItemBoundary:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -1129,10 +1129,10 @@ - get: MonoTouch.Foundation.Export("isVertical", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("isVertical", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setVertical:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setVertical:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -1153,10 +1153,10 @@ - get: MonoTouch.Foundation.Export("viewpointOffset", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("viewpointOffset", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setViewpointOffset:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setViewpointOffset:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -1177,10 +1177,10 @@ - get: MonoTouch.Foundation.Export("dataSource", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("dataSource", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setDataSource:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setDataSource:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -1201,10 +1201,10 @@ - get: MonoTouch.Foundation.Export("delegate", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("delegate", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) - set: MonoTouch.Foundation.Export("setDelegate:", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + set: MonoTouch.Foundation.Export("setDelegate:", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) @@ -1225,7 +1225,7 @@ - get: MonoTouch.Foundation.Export("isWrapEnabled", MonoTouch.ObjCRuntime.ArgumentSemantic.Assign) + get: MonoTouch.Foundation.Export("isWrapEnabled", MonoTouch.ObjCRuntime.ArgumentSemantic.UnsafeUnretained) diff --git a/iCarousel/docs/iCarouselSDK/iCarouselDataSource.xml b/iCarousel/docs/iCarouselSDK/iCarouselDataSource.xml index 8974d3f0..f9c01d93 100644 --- a/iCarousel/docs/iCarouselSDK/iCarouselDataSource.xml +++ b/iCarousel/docs/iCarouselSDK/iCarouselDataSource.xml @@ -1,6 +1,6 @@ - - + + iCarouselSDK 0.0.0.0 @@ -8,11 +8,21 @@ MonoTouch.Foundation.NSObject - + + + iCarouselSDK.IiCarouselDataSource + + + System.IDisposable + + MonoTouch.Foundation.Model + + MonoTouch.Foundation.Protocol + MonoTouch.Foundation.Register("iCarouselDataSource", true) diff --git a/iCarousel/docs/iCarouselSDK/iCarouselDataSource_Extensions.xml b/iCarousel/docs/iCarouselSDK/iCarouselDataSource_Extensions.xml new file mode 100644 index 00000000..4b230105 --- /dev/null +++ b/iCarousel/docs/iCarouselSDK/iCarouselDataSource_Extensions.xml @@ -0,0 +1,66 @@ + + + + + iCarouselSDK + 0.0.0.0 + + + System.Object + + + + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.UInt32 + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + MonoTouch.UIKit.UIView + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + diff --git a/iCarousel/docs/iCarouselSDK/iCarouselDelegate.xml b/iCarousel/docs/iCarouselSDK/iCarouselDelegate.xml index b5876f8e..201d8c8b 100644 --- a/iCarousel/docs/iCarouselSDK/iCarouselDelegate.xml +++ b/iCarousel/docs/iCarouselSDK/iCarouselDelegate.xml @@ -1,6 +1,6 @@ - - + + iCarouselSDK 0.0.0.0 @@ -8,11 +8,21 @@ MonoTouch.Foundation.NSObject - + + + iCarouselSDK.IiCarouselDelegate + + + System.IDisposable + + MonoTouch.Foundation.Model + + MonoTouch.Foundation.Protocol + MonoTouch.Foundation.Register("iCarouselDelegate", true) diff --git a/iCarousel/docs/iCarouselSDK/iCarouselDelegate_Extensions.xml b/iCarousel/docs/iCarouselSDK/iCarouselDelegate_Extensions.xml new file mode 100644 index 00000000..7db5f3c0 --- /dev/null +++ b/iCarousel/docs/iCarouselSDK/iCarouselDelegate_Extensions.xml @@ -0,0 +1,309 @@ + + + + + iCarouselSDK + 0.0.0.0 + + + System.Object + + + + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + MonoTouch.CoreAnimation.CATransform3D + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Single + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Boolean + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Single + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + diff --git a/iCarousel/docs/index.xml b/iCarousel/docs/index.xml index 5ddd6802..521adf06 100644 --- a/iCarousel/docs/index.xml +++ b/iCarousel/docs/index.xml @@ -8,6 +8,9 @@ System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true) + + System.Runtime.Versioning.TargetFramework("MonoTouch,Version=v1.0", FrameworkDisplayName="") + @@ -20,10 +23,379 @@ + + + + iCarouselSDK + + + + + + + + + ExtensionMethod + + System.UInt32 + + + + + + + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + MonoTouch.UIKit.UIView + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Void + + + + + + + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Void + + + + + + + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Void + + + + + + + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Void + + + + + + + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Void + + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + MonoTouch.CoreAnimation.CATransform3D + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Single + + + + + + + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Boolean + + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Single + + + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Void + + + + + + + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Void + + + + + + + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Void + + + + + + + To be added. + To be added. + To be added. + + + + + diff --git a/iCarousel/native-source/iCarousel/build-static-lib b/iCarousel/native-source/iCarousel/build-static-lib new file mode 100755 index 00000000..aa31b235 --- /dev/null +++ b/iCarousel/native-source/iCarousel/build-static-lib @@ -0,0 +1,5 @@ +#!/bin/bash + +xcodebuild -project "iCarousel.xcodeproj" -sdk iphonesimulator -configuration Release clean build +xcodebuild -project "iCarousel.xcodeproj" -sdk iphoneos -configuration Release clean build +lipo -create -output ./build/libiCarousel.a ./build/Release-iphoneos/libiCarousel.a ./build/Release-iphonesimulator/libiCarousel.a \ No newline at end of file diff --git a/iCarousel/native-source/iCarousel/iCarousel.xcodeproj/project.pbxproj b/iCarousel/native-source/iCarousel/iCarousel.xcodeproj/project.pbxproj new file mode 100644 index 00000000..ac0a99f8 --- /dev/null +++ b/iCarousel/native-source/iCarousel/iCarousel.xcodeproj/project.pbxproj @@ -0,0 +1,247 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 37E5208C1A5ECD8100119980 /* iCarousel.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 37E5208B1A5ECD8100119980 /* iCarousel.h */; }; + 37E5208E1A5ECD8100119980 /* iCarousel.m in Sources */ = {isa = PBXBuildFile; fileRef = 37E5208D1A5ECD8100119980 /* iCarousel.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 37E520861A5ECD8100119980 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + 37E5208C1A5ECD8100119980 /* iCarousel.h in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 37E520881A5ECD8100119980 /* libiCarousel.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libiCarousel.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 37E5208B1A5ECD8100119980 /* iCarousel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = iCarousel.h; sourceTree = ""; }; + 37E5208D1A5ECD8100119980 /* iCarousel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iCarousel.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 37E520851A5ECD8100119980 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 37E5207F1A5ECD8100119980 = { + isa = PBXGroup; + children = ( + 37E5208A1A5ECD8100119980 /* iCarousel */, + 37E520891A5ECD8100119980 /* Products */, + ); + sourceTree = ""; + }; + 37E520891A5ECD8100119980 /* Products */ = { + isa = PBXGroup; + children = ( + 37E520881A5ECD8100119980 /* libiCarousel.a */, + ); + name = Products; + sourceTree = ""; + }; + 37E5208A1A5ECD8100119980 /* iCarousel */ = { + isa = PBXGroup; + children = ( + 37E5208B1A5ECD8100119980 /* iCarousel.h */, + 37E5208D1A5ECD8100119980 /* iCarousel.m */, + ); + path = iCarousel; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 37E520871A5ECD8100119980 /* iCarousel */ = { + isa = PBXNativeTarget; + buildConfigurationList = 37E5209C1A5ECD8100119980 /* Build configuration list for PBXNativeTarget "iCarousel" */; + buildPhases = ( + 37E520841A5ECD8100119980 /* Sources */, + 37E520851A5ECD8100119980 /* Frameworks */, + 37E520861A5ECD8100119980 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iCarousel; + productName = iCarousel; + productReference = 37E520881A5ECD8100119980 /* libiCarousel.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 37E520801A5ECD8100119980 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = "Nicolas Verinaud"; + TargetAttributes = { + 37E520871A5ECD8100119980 = { + CreatedOnToolsVersion = 6.1.1; + }; + }; + }; + buildConfigurationList = 37E520831A5ECD8100119980 /* Build configuration list for PBXProject "iCarousel" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 37E5207F1A5ECD8100119980; + productRefGroup = 37E520891A5ECD8100119980 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 37E520871A5ECD8100119980 /* iCarousel */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 37E520841A5ECD8100119980 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 37E5208E1A5ECD8100119980 /* iCarousel.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 37E5209A1A5ECD8100119980 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 37E5209B1A5ECD8100119980 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 37E5209D1A5ECD8100119980 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + 37E5209E1A5ECD8100119980 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 37E520831A5ECD8100119980 /* Build configuration list for PBXProject "iCarousel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 37E5209A1A5ECD8100119980 /* Debug */, + 37E5209B1A5ECD8100119980 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 37E5209C1A5ECD8100119980 /* Build configuration list for PBXNativeTarget "iCarousel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 37E5209D1A5ECD8100119980 /* Debug */, + 37E5209E1A5ECD8100119980 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 37E520801A5ECD8100119980 /* Project object */; +} diff --git a/iCarousel/native-source/iCarousel/iCarousel.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/iCarousel/native-source/iCarousel/iCarousel.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..6ba1c57a --- /dev/null +++ b/iCarousel/native-source/iCarousel/iCarousel.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/iCarousel/native-source/iCarousel/iCarousel.xcodeproj/project.xcworkspace/xcshareddata/iCarousel.xccheckout b/iCarousel/native-source/iCarousel/iCarousel.xcodeproj/project.xcworkspace/xcshareddata/iCarousel.xccheckout new file mode 100644 index 00000000..e0db70f8 --- /dev/null +++ b/iCarousel/native-source/iCarousel/iCarousel.xcodeproj/project.xcworkspace/xcshareddata/iCarousel.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 0620184C-2122-41AB-842A-9CCC2B22C1E5 + IDESourceControlProjectName + iCarousel + IDESourceControlProjectOriginsDictionary + + 0535128BDD409F8BC0DA4523C90C07175AAFCF00 + https://github.com/nverinaud/monotouch-bindings.git + + IDESourceControlProjectPath + iCarousel/native-source/iCarousel/iCarousel.xcodeproj + IDESourceControlProjectRelativeInstallPathDictionary + + 0535128BDD409F8BC0DA4523C90C07175AAFCF00 + ../../../../.. + + IDESourceControlProjectURL + https://github.com/nverinaud/monotouch-bindings.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + 0535128BDD409F8BC0DA4523C90C07175AAFCF00 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + 0535128BDD409F8BC0DA4523C90C07175AAFCF00 + IDESourceControlWCCName + monotouch-bindings + + + + diff --git a/iCarousel/native-source/iCarousel/iCarousel/iCarousel.h b/iCarousel/native-source/iCarousel/iCarousel/iCarousel.h new file mode 100644 index 00000000..53350915 --- /dev/null +++ b/iCarousel/native-source/iCarousel/iCarousel/iCarousel.h @@ -0,0 +1,197 @@ +// +// iCarousel.h +// +// Version 1.8.1 +// +// Created by Nick Lockwood on 01/04/2011. +// Copyright 2011 Charcoal Design +// +// Distributed under the permissive zlib License +// Get the latest version from here: +// +// https://github.com/nicklockwood/iCarousel +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis" + + +#import +#undef weak_delegate +#undef __weak_delegate +#if __has_feature(objc_arc) && __has_feature(objc_arc_weak) && \ +(!(defined __MAC_OS_X_VERSION_MIN_REQUIRED) || \ +__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8) +#define weak_delegate weak +#else +#define weak_delegate unsafe_unretained +#endif + + +#import +#if defined USING_CHAMELEON || defined __IPHONE_OS_VERSION_MAX_ALLOWED +#define ICAROUSEL_IOS +#else +#define ICAROUSEL_MACOS +#endif + + +#ifdef ICAROUSEL_IOS +#import +#else +#import +typedef NSView UIView; +#endif + + +typedef NS_ENUM(NSInteger, iCarouselType) +{ + iCarouselTypeLinear = 0, + iCarouselTypeRotary, + iCarouselTypeInvertedRotary, + iCarouselTypeCylinder, + iCarouselTypeInvertedCylinder, + iCarouselTypeWheel, + iCarouselTypeInvertedWheel, + iCarouselTypeCoverFlow, + iCarouselTypeCoverFlow2, + iCarouselTypeTimeMachine, + iCarouselTypeInvertedTimeMachine, + iCarouselTypeCustom +}; + + +typedef NS_ENUM(NSInteger, iCarouselOption) +{ + iCarouselOptionWrap = 0, + iCarouselOptionShowBackfaces, + iCarouselOptionOffsetMultiplier, + iCarouselOptionVisibleItems, + iCarouselOptionCount, + iCarouselOptionArc, + iCarouselOptionAngle, + iCarouselOptionRadius, + iCarouselOptionTilt, + iCarouselOptionSpacing, + iCarouselOptionFadeMin, + iCarouselOptionFadeMax, + iCarouselOptionFadeRange, + iCarouselOptionFadeMinAlpha +}; + + +@protocol iCarouselDataSource, iCarouselDelegate; + +@interface iCarousel : UIView + +@property (nonatomic, weak_delegate) IBOutlet id dataSource; +@property (nonatomic, weak_delegate) IBOutlet id delegate; +@property (nonatomic, assign) iCarouselType type; +@property (nonatomic, assign) CGFloat perspective; +@property (nonatomic, assign) CGFloat decelerationRate; +@property (nonatomic, assign) CGFloat scrollSpeed; +@property (nonatomic, assign) CGFloat bounceDistance; +@property (nonatomic, assign, getter = isScrollEnabled) BOOL scrollEnabled; +@property (nonatomic, assign, getter = isPagingEnabled) BOOL pagingEnabled; +@property (nonatomic, assign, getter = isVertical) BOOL vertical; +@property (nonatomic, readonly, getter = isWrapEnabled) BOOL wrapEnabled; +@property (nonatomic, assign) BOOL bounces; +@property (nonatomic, assign) CGFloat scrollOffset; +@property (nonatomic, readonly) CGFloat offsetMultiplier; +@property (nonatomic, assign) CGSize contentOffset; +@property (nonatomic, assign) CGSize viewpointOffset; +@property (nonatomic, readonly) NSInteger numberOfItems; +@property (nonatomic, readonly) NSInteger numberOfPlaceholders; +@property (nonatomic, assign) NSInteger currentItemIndex; +@property (nonatomic, strong, readonly) UIView *currentItemView; +@property (nonatomic, strong, readonly) NSArray *indexesForVisibleItems; +@property (nonatomic, readonly) NSInteger numberOfVisibleItems; +@property (nonatomic, strong, readonly) NSArray *visibleItemViews; +@property (nonatomic, readonly) CGFloat itemWidth; +@property (nonatomic, strong, readonly) UIView *contentView; +@property (nonatomic, readonly) CGFloat toggle; +@property (nonatomic, assign) CGFloat autoscroll; +@property (nonatomic, assign) BOOL stopAtItemBoundary; +@property (nonatomic, assign) BOOL scrollToItemBoundary; +@property (nonatomic, assign) BOOL ignorePerpendicularSwipes; +@property (nonatomic, assign) BOOL centerItemWhenSelected; +@property (nonatomic, readonly, getter = isDragging) BOOL dragging; +@property (nonatomic, readonly, getter = isDecelerating) BOOL decelerating; +@property (nonatomic, readonly, getter = isScrolling) BOOL scrolling; + +- (void)scrollByOffset:(CGFloat)offset duration:(NSTimeInterval)duration; +- (void)scrollToOffset:(CGFloat)offset duration:(NSTimeInterval)duration; +- (void)scrollByNumberOfItems:(NSInteger)itemCount duration:(NSTimeInterval)duration; +- (void)scrollToItemAtIndex:(NSInteger)index duration:(NSTimeInterval)duration; +- (void)scrollToItemAtIndex:(NSInteger)index animated:(BOOL)animated; + +- (UIView *)itemViewAtIndex:(NSInteger)index; +- (NSInteger)indexOfItemView:(UIView *)view; +- (NSInteger)indexOfItemViewOrSubview:(UIView *)view; +- (CGFloat)offsetForItemAtIndex:(NSInteger)index; +- (UIView *)itemViewAtPoint:(CGPoint)point; + +- (void)removeItemAtIndex:(NSInteger)index animated:(BOOL)animated; +- (void)insertItemAtIndex:(NSInteger)index animated:(BOOL)animated; +- (void)reloadItemAtIndex:(NSInteger)index animated:(BOOL)animated; + +- (void)reloadData; + +@end + + +@protocol iCarouselDataSource + +- (NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel; +- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view; + +@optional + +- (NSInteger)numberOfPlaceholdersInCarousel:(iCarousel *)carousel; +- (UIView *)carousel:(iCarousel *)carousel placeholderViewAtIndex:(NSInteger)index reusingView:(UIView *)view; + +@end + + +@protocol iCarouselDelegate +@optional + +- (void)carouselWillBeginScrollingAnimation:(iCarousel *)carousel; +- (void)carouselDidEndScrollingAnimation:(iCarousel *)carousel; +- (void)carouselDidScroll:(iCarousel *)carousel; +- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel; +- (void)carouselWillBeginDragging:(iCarousel *)carousel; +- (void)carouselDidEndDragging:(iCarousel *)carousel willDecelerate:(BOOL)decelerate; +- (void)carouselWillBeginDecelerating:(iCarousel *)carousel; +- (void)carouselDidEndDecelerating:(iCarousel *)carousel; + +- (BOOL)carousel:(iCarousel *)carousel shouldSelectItemAtIndex:(NSInteger)index; +- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index; + +- (CGFloat)carouselItemWidth:(iCarousel *)carousel; +- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform; +- (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value; + +@end + +#pragma GCC diagnostic pop + diff --git a/iCarousel/native-source/iCarousel/iCarousel/iCarousel.m b/iCarousel/native-source/iCarousel/iCarousel/iCarousel.m new file mode 100644 index 00000000..be33a13f --- /dev/null +++ b/iCarousel/native-source/iCarousel/iCarousel/iCarousel.m @@ -0,0 +1,2323 @@ +// +// iCarousel.m +// +// Version 1.8.1 +// +// Created by Nick Lockwood on 01/04/2011. +// Copyright 2011 Charcoal Design +// +// Distributed under the permissive zlib License +// Get the latest version from here: +// +// https://github.com/nicklockwood/iCarousel +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// + +#import "iCarousel.h" +#import + + +#import +#if !__has_feature(objc_arc) +#error This class requires automatic reference counting +#endif + + +#pragma GCC diagnostic ignored "-Wreceiver-is-weak" +#pragma GCC diagnostic ignored "-Warc-repeated-use-of-weak" +#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis" +#pragma GCC diagnostic ignored "-Wdirect-ivar-access" +#pragma GCC diagnostic ignored "-Wunused-macros" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#pragma GCC diagnostic ignored "-Wselector" +#pragma GCC diagnostic ignored "-Wgnu" + + +#define MIN_TOGGLE_DURATION 0.2 +#define MAX_TOGGLE_DURATION 0.4 +#define SCROLL_DURATION 0.4 +#define INSERT_DURATION 0.4 +#define DECELERATE_THRESHOLD 0.1 +#define SCROLL_SPEED_THRESHOLD 2.0 +#define SCROLL_DISTANCE_THRESHOLD 0.1 +#define DECELERATION_MULTIPLIER 30.0 +#define FLOAT_ERROR_MARGIN 0.000001 + +#ifdef ICAROUSEL_MACOS +#define MAX_VISIBLE_ITEMS 50 +#else +#define MAX_VISIBLE_ITEMS 30 +#endif + + +@implementation NSObject (iCarousel) + +- (NSUInteger)numberOfPlaceholdersInCarousel:(__unused iCarousel *)carousel { return 0; } +- (void)carouselWillBeginScrollingAnimation:(__unused iCarousel *)carousel {} +- (void)carouselDidEndScrollingAnimation:(__unused iCarousel *)carousel {} +- (void)carouselDidScroll:(__unused iCarousel *)carousel {} + +- (void)carouselCurrentItemIndexDidChange:(__unused iCarousel *)carousel {} +- (void)carouselWillBeginDragging:(__unused iCarousel *)carousel {} +- (void)carouselDidEndDragging:(__unused iCarousel *)carousel willDecelerate:(__unused BOOL)decelerate {} +- (void)carouselWillBeginDecelerating:(__unused iCarousel *)carousel {} +- (void)carouselDidEndDecelerating:(__unused iCarousel *)carousel {} + +- (BOOL)carousel:(__unused iCarousel *)carousel shouldSelectItemAtIndex:(__unused NSInteger)index { return YES; } +- (void)carousel:(__unused iCarousel *)carousel didSelectItemAtIndex:(__unused NSInteger)index {} + +- (CGFloat)carouselItemWidth:(__unused iCarousel *)carousel { return 0; } +- (CATransform3D)carousel:(__unused iCarousel *)carousel + itemTransformForOffset:(__unused CGFloat)offset + baseTransform:(CATransform3D)transform { return transform; } +- (CGFloat)carousel:(__unused iCarousel *)carousel + valueForOption:(__unused iCarouselOption)option + withDefault:(CGFloat)value { return value; } + +@end + + +@interface iCarousel () + +@property (nonatomic, strong) UIView *contentView; +@property (nonatomic, strong) NSMutableDictionary *itemViews; +@property (nonatomic, strong) NSMutableSet *itemViewPool; +@property (nonatomic, strong) NSMutableSet *placeholderViewPool; +@property (nonatomic, assign) CGFloat previousScrollOffset; +@property (nonatomic, assign) NSInteger previousItemIndex; +@property (nonatomic, assign) NSInteger numberOfPlaceholdersToShow; +@property (nonatomic, assign) NSInteger numberOfVisibleItems; +@property (nonatomic, assign) CGFloat itemWidth; +@property (nonatomic, assign) CGFloat offsetMultiplier; +@property (nonatomic, assign) CGFloat startOffset; +@property (nonatomic, assign) CGFloat endOffset; +@property (nonatomic, assign) NSTimeInterval scrollDuration; +@property (nonatomic, assign, getter = isScrolling) BOOL scrolling; +@property (nonatomic, assign) NSTimeInterval startTime; +@property (nonatomic, assign) NSTimeInterval lastTime; +@property (nonatomic, assign) CGFloat startVelocity; +@property (nonatomic, strong) NSTimer *timer; +@property (nonatomic, assign, getter = isDecelerating) BOOL decelerating; +@property (nonatomic, assign) CGFloat previousTranslation; +@property (nonatomic, assign, getter = isWrapEnabled) BOOL wrapEnabled; +@property (nonatomic, assign, getter = isDragging) BOOL dragging; +@property (nonatomic, assign) BOOL didDrag; +@property (nonatomic, assign) NSTimeInterval toggleTime; + +NSComparisonResult compareViewDepth(UIView *view1, UIView *view2, iCarousel *self); + +@end + + +@implementation iCarousel + +#pragma mark - +#pragma mark Initialisation + +- (void)setUp +{ + _decelerationRate = 0.95; + _scrollEnabled = YES; + _bounces = YES; + _offsetMultiplier = 1.0; + _perspective = -1.0/500.0; + _contentOffset = CGSizeZero; + _viewpointOffset = CGSizeZero; + _scrollSpeed = 1.0; + _bounceDistance = 1.0; + _stopAtItemBoundary = YES; + _scrollToItemBoundary = YES; + _ignorePerpendicularSwipes = YES; + _centerItemWhenSelected = YES; + + _contentView = [[UIView alloc] initWithFrame:self.bounds]; + + +#ifdef ICAROUSEL_IOS + + _contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + + //add pan gesture recogniser + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didPan:)]; + panGesture.delegate = (id )self; + [_contentView addGestureRecognizer:panGesture]; + + //add tap gesture recogniser + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTap:)]; + tapGesture.delegate = (id )self; + [_contentView addGestureRecognizer:tapGesture]; + + //set up accessibility + self.accessibilityTraits = UIAccessibilityTraitAllowsDirectInteraction; + self.isAccessibilityElement = YES; + +#else + + [_contentView setWantsLayer:YES]; + +#endif + + [self addSubview:_contentView]; + + if (_dataSource) + { + [self reloadData]; + } +} + +#ifndef USING_CHAMELEON + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + if ((self = [super initWithCoder:aDecoder])) + { + [self setUp]; + if (self.superview) + { + [self startAnimation]; + } + } + return self; +} + +#endif + +#ifdef ICAROUSEL_IOS + +- (id)initWithFrame:(CGRect)frame + +#else + +- (id)initWithFrame:(NSRect)frame + +#endif + +{ + if ((self = [super initWithFrame:frame])) + { + [self setUp]; + } + return self; +} + +- (void)dealloc +{ + [self stopAnimation]; +} + +- (void)setDataSource:(id)dataSource +{ + if (_dataSource != dataSource) + { + _dataSource = dataSource; + if (_dataSource) + { + [self reloadData]; + } + } +} + +- (void)setDelegate:(id)delegate +{ + if (_delegate != delegate) + { + _delegate = delegate; + if (_delegate && _dataSource) + { + [self setNeedsLayout]; + } + } +} + +- (void)setType:(iCarouselType)type +{ + if (_type != type) + { + _type = type; + [self layOutItemViews]; + } +} + +- (void)setVertical:(BOOL)vertical +{ + if (_vertical != vertical) + { + _vertical = vertical; + [self layOutItemViews]; + } +} + +- (void)setScrollOffset:(CGFloat)scrollOffset +{ + _scrolling = NO; + _decelerating = NO; + _startOffset = scrollOffset; + _endOffset = scrollOffset; + + if (fabs(_scrollOffset - scrollOffset) > 0.0) + { + _scrollOffset = scrollOffset; + [self depthSortViews]; + [self didScroll]; + } +} + +- (void)setCurrentItemIndex:(NSInteger)currentItemIndex +{ + [self setScrollOffset:currentItemIndex]; +} + +- (void)setPerspective:(CGFloat)perspective +{ + _perspective = perspective; + [self transformItemViews]; +} + +- (void)setViewpointOffset:(CGSize)viewpointOffset +{ + if (!CGSizeEqualToSize(_viewpointOffset, viewpointOffset)) + { + _viewpointOffset = viewpointOffset; + [self transformItemViews]; + } +} + +- (void)setContentOffset:(CGSize)contentOffset +{ + if (!CGSizeEqualToSize(_contentOffset, contentOffset)) + { + _contentOffset = contentOffset; + [self layOutItemViews]; + } +} + +- (void)setAutoscroll:(CGFloat)autoscroll +{ + _autoscroll = autoscroll; + if (autoscroll != 0.0) [self startAnimation]; +} + +- (void)pushAnimationState:(BOOL)enabled +{ + [CATransaction begin]; + [CATransaction setDisableActions:!enabled]; +} + +- (void)popAnimationState +{ + [CATransaction commit]; +} + + +#pragma mark - +#pragma mark View management + +- (NSArray *)indexesForVisibleItems +{ + return [[_itemViews allKeys] sortedArrayUsingSelector:@selector(compare:)]; +} + +- (NSArray *)visibleItemViews +{ + NSArray *indexes = [self indexesForVisibleItems]; + return [_itemViews objectsForKeys:indexes notFoundMarker:[NSNull null]]; +} + +- (UIView *)itemViewAtIndex:(NSInteger)index +{ + return _itemViews[@(index)]; +} + +- (UIView *)currentItemView +{ + return [self itemViewAtIndex:self.currentItemIndex]; +} + +- (NSInteger)indexOfItemView:(UIView *)view +{ + NSInteger index = [[_itemViews allValues] indexOfObject:view]; + if (index != NSNotFound) + { + return [[_itemViews allKeys][index] integerValue]; + } + return NSNotFound; +} + +- (NSInteger)indexOfItemViewOrSubview:(UIView *)view +{ + NSInteger index = [self indexOfItemView:view]; + if (index == NSNotFound && view != nil && view != _contentView) + { + return [self indexOfItemViewOrSubview:view.superview]; + } + return index; +} + +- (UIView *)itemViewAtPoint:(CGPoint)point +{ + for (UIView *view in [[[_itemViews allValues] sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))compareViewDepth context:(__bridge void *)self] reverseObjectEnumerator]) + { + if ([view.superview.layer hitTest:point]) + { + return view; + } + } + return nil; +} + +- (void)setItemView:(UIView *)view forIndex:(NSInteger)index +{ + _itemViews[@(index)] = view; +} + +- (void)removeViewAtIndex:(NSInteger)index +{ + NSMutableDictionary *newItemViews = [NSMutableDictionary dictionaryWithCapacity:[_itemViews count] - 1]; + for (NSNumber *number in [self indexesForVisibleItems]) + { + NSInteger i = [number integerValue]; + if (i < index) + { + newItemViews[number] = _itemViews[number]; + } + else if (i > index) + { + newItemViews[@(i - 1)] = _itemViews[number]; + } + } + self.itemViews = newItemViews; +} + +- (void)insertView:(UIView *)view atIndex:(NSInteger)index +{ + NSMutableDictionary *newItemViews = [NSMutableDictionary dictionaryWithCapacity:[_itemViews count] + 1]; + for (NSNumber *number in [self indexesForVisibleItems]) + { + NSInteger i = [number integerValue]; + if (i < index) + { + newItemViews[number] = _itemViews[number]; + } + else + { + newItemViews[@(i + 1)] = _itemViews[number]; + } + } + if (view) + { + [self setItemView:view forIndex:index]; + } + self.itemViews = newItemViews; +} + + +#pragma mark - +#pragma mark View layout + +- (CGFloat)alphaForItemWithOffset:(CGFloat)offset +{ + CGFloat fadeMin = -INFINITY; + CGFloat fadeMax = INFINITY; + CGFloat fadeRange = 1.0; + CGFloat fadeMinAlpha = 0.0; + switch (_type) + { + case iCarouselTypeTimeMachine: + { + fadeMax = 0.0; + break; + } + case iCarouselTypeInvertedTimeMachine: + { + fadeMin = 0.0; + break; + } + case iCarouselTypeCoverFlow: + case iCarouselTypeCoverFlow2: + case iCarouselTypeCustom: + case iCarouselTypeCylinder: + case iCarouselTypeInvertedCylinder: + case iCarouselTypeRotary: + case iCarouselTypeInvertedRotary: + case iCarouselTypeWheel: + case iCarouselTypeInvertedWheel: + case iCarouselTypeLinear: + { + //do nothing + } + } + fadeMin = [self valueForOption:iCarouselOptionFadeMin withDefault:fadeMin]; + fadeMax = [self valueForOption:iCarouselOptionFadeMax withDefault:fadeMax]; + fadeRange = [self valueForOption:iCarouselOptionFadeRange withDefault:fadeRange]; + fadeMinAlpha = [self valueForOption:iCarouselOptionFadeMinAlpha withDefault:fadeMinAlpha]; + +#ifdef ICAROUSEL_MACOS + + if (_vertical) + { + //invert + offset = -offset; + } + +#endif + + CGFloat factor = 0.0; + if (offset > fadeMax) + { + factor = offset - fadeMax; + } + else if (offset < fadeMin) + { + factor = fadeMin - offset; + } + return 1.0 - MIN(factor, fadeRange) / fadeRange * (1.0 - fadeMinAlpha); +} + +- (CGFloat)valueForOption:(iCarouselOption)option withDefault:(CGFloat)value +{ + return _delegate? [_delegate carousel:self valueForOption:option withDefault:value]: value; +} + +- (CATransform3D)transformForItemViewWithOffset:(CGFloat)offset +{ + //set up base transform + CATransform3D transform = CATransform3DIdentity; + transform.m34 = _perspective; + transform = CATransform3DTranslate(transform, -_viewpointOffset.width, -_viewpointOffset.height, 0.0); + + //perform transform + switch (_type) + { + case iCarouselTypeCustom: + { + return [_delegate carousel:self itemTransformForOffset:offset baseTransform:transform]; + } + case iCarouselTypeLinear: + { + CGFloat spacing = [self valueForOption:iCarouselOptionSpacing withDefault:1.0]; + if (_vertical) + { + return CATransform3DTranslate(transform, 0.0, offset * _itemWidth * spacing, 0.0); + } + else + { + return CATransform3DTranslate(transform, offset * _itemWidth * spacing, 0.0, 0.0); + } + } + case iCarouselTypeRotary: + case iCarouselTypeInvertedRotary: + { + CGFloat count = [self circularCarouselItemCount]; + CGFloat spacing = [self valueForOption:iCarouselOptionSpacing withDefault:1.0]; + CGFloat arc = [self valueForOption:iCarouselOptionArc withDefault:M_PI * 2.0]; + CGFloat radius = [self valueForOption:iCarouselOptionRadius withDefault:MAX(_itemWidth * spacing / 2.0, _itemWidth * spacing / 2.0 / tanf(arc/2.0/count))]; + CGFloat angle = [self valueForOption:iCarouselOptionAngle withDefault:offset / count * arc]; + + if (_type == iCarouselTypeInvertedRotary) + { + radius = -radius; + angle = -angle; + } + + if (_vertical) + { + return CATransform3DTranslate(transform, 0.0, radius * sin(angle), radius * cos(angle) - radius); + } + else + { + return CATransform3DTranslate(transform, radius * sin(angle), 0.0, radius * cos(angle) - radius); + } + } + case iCarouselTypeCylinder: + case iCarouselTypeInvertedCylinder: + { + CGFloat count = [self circularCarouselItemCount]; + CGFloat spacing = [self valueForOption:iCarouselOptionSpacing withDefault:1.0]; + CGFloat arc = [self valueForOption:iCarouselOptionArc withDefault:M_PI * 2.0]; + CGFloat radius = [self valueForOption:iCarouselOptionRadius withDefault:MAX(0.01, _itemWidth * spacing / 2.0 / tanf(arc/2.0/count))]; + CGFloat angle = [self valueForOption:iCarouselOptionAngle withDefault:offset / count * arc]; + + if (_type == iCarouselTypeInvertedCylinder) + { + radius = -radius; + angle = -angle; + } + + if (_vertical) + { + transform = CATransform3DTranslate(transform, 0.0, 0.0, -radius); + transform = CATransform3DRotate(transform, angle, -1.0, 0.0, 0.0); + return CATransform3DTranslate(transform, 0.0, 0.0, radius + 0.01); + } + else + { + transform = CATransform3DTranslate(transform, 0.0, 0.0, -radius); + transform = CATransform3DRotate(transform, angle, 0.0, 1.0, 0.0); + return CATransform3DTranslate(transform, 0.0, 0.0, radius + 0.01); + } + } + case iCarouselTypeWheel: + case iCarouselTypeInvertedWheel: + { + CGFloat count = [self circularCarouselItemCount]; + CGFloat spacing = [self valueForOption:iCarouselOptionSpacing withDefault:1.0]; + CGFloat arc = [self valueForOption:iCarouselOptionArc withDefault:M_PI * 2.0]; + CGFloat radius = [self valueForOption:iCarouselOptionRadius withDefault:_itemWidth * spacing * count / arc]; + CGFloat angle = [self valueForOption:iCarouselOptionAngle withDefault:arc / count]; + + if (_type == iCarouselTypeInvertedWheel) + { + radius = -radius; + angle = -angle; + } + + if (_vertical) + { + transform = CATransform3DTranslate(transform, -radius, 0.0, 0.0); + transform = CATransform3DRotate(transform, angle * offset, 0.0, 0.0, 1.0); + return CATransform3DTranslate(transform, radius, 0.0, offset * 0.01); + } + else + { + transform = CATransform3DTranslate(transform, 0.0, radius, 0.0); + transform = CATransform3DRotate(transform, angle * offset, 0.0, 0.0, 1.0); + return CATransform3DTranslate(transform, 0.0, -radius, offset * 0.01); + } + } + case iCarouselTypeCoverFlow: + case iCarouselTypeCoverFlow2: + { + CGFloat tilt = [self valueForOption:iCarouselOptionTilt withDefault:0.9f]; + CGFloat spacing = [self valueForOption:iCarouselOptionSpacing withDefault:0.25]; + CGFloat clampedOffset = MAX(-1.0, MIN(1.0, offset)); + + if (_type == iCarouselTypeCoverFlow2) + { + if (_toggle > 0.0) + { + if (offset <= -0.5) + { + clampedOffset = -1.0; + } + else if (offset <= 0.5) + { + clampedOffset = -_toggle; + } + else if (offset <= 1.5) + { + clampedOffset = 1.0 - _toggle; + } + } + else + { + if (offset > 0.5) + { + clampedOffset = 1.0; + } + else if (offset > -0.5) + { + clampedOffset = -_toggle; + } + else if (offset > -1.5) + { + clampedOffset = - 1.0 - _toggle; + } + } + } + + CGFloat x = (clampedOffset * 0.5 * tilt + offset * spacing) * _itemWidth; + CGFloat z = fabs(clampedOffset) * -_itemWidth * 0.5; + + if (_vertical) + { + transform = CATransform3DTranslate(transform, 0.0, x, z); + return CATransform3DRotate(transform, -clampedOffset * M_PI_2 * tilt, -1.0, 0.0, 0.0); + } + else + { + transform = CATransform3DTranslate(transform, x, 0.0, z); + return CATransform3DRotate(transform, -clampedOffset * M_PI_2 * tilt, 0.0, 1.0, 0.0); + } + } + case iCarouselTypeTimeMachine: + case iCarouselTypeInvertedTimeMachine: + { + CGFloat tilt = [self valueForOption:iCarouselOptionTilt withDefault:0.3f]; + CGFloat spacing = [self valueForOption:iCarouselOptionSpacing withDefault:1.0]; + + if (_type == iCarouselTypeInvertedTimeMachine) + { + tilt = -tilt; + offset = -offset; + } + + if (_vertical) + { + +#ifdef ICAROUSEL_MACOS + + //invert again + tilt = -tilt; + offset = -offset; + +#endif + return CATransform3DTranslate(transform, 0.0, offset * _itemWidth * tilt, offset * _itemWidth * spacing); + } + else + { + return CATransform3DTranslate(transform, offset * _itemWidth * tilt, 0.0, offset * _itemWidth * spacing); + } + } + } +} + +NSComparisonResult compareViewDepth(UIView *view1, UIView *view2, iCarousel *self) +{ + //compare depths + CATransform3D t1 = view1.superview.layer.transform; + CATransform3D t2 = view2.superview.layer.transform; + CGFloat z1 = t1.m13 + t1.m23 + t1.m33 + t1.m43; + CGFloat z2 = t2.m13 + t2.m23 + t2.m33 + t2.m43; + CGFloat difference = z1 - z2; + + //if depths are equal, compare distance from current view + if (difference == 0.0) + { + CATransform3D t3 = [self currentItemView].superview.layer.transform; + if (self.vertical) + { + CGFloat y1 = t1.m12 + t1.m22 + t1.m32 + t1.m42; + CGFloat y2 = t2.m12 + t2.m22 + t2.m32 + t2.m42; + CGFloat y3 = t3.m12 + t3.m22 + t3.m32 + t3.m42; + difference = fabs(y2 - y3) - fabs(y1 - y3); + } + else + { + CGFloat x1 = t1.m11 + t1.m21 + t1.m31 + t1.m41; + CGFloat x2 = t2.m11 + t2.m21 + t2.m31 + t2.m41; + CGFloat x3 = t3.m11 + t3.m21 + t3.m31 + t3.m41; + difference = fabs(x2 - x3) - fabs(x1 - x3); + } + } + return (difference < 0.0)? NSOrderedAscending: NSOrderedDescending; +} + +#ifdef ICAROUSEL_IOS + +- (void)depthSortViews +{ + for (UIView *view in [[_itemViews allValues] sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))compareViewDepth context:(__bridge void *)self]) + { + [_contentView bringSubviewToFront:view.superview]; + } +} + +#else + +- (void)setNeedsLayout +{ + [self setNeedsLayout:YES]; +} + +- (void)depthSortViews +{ + //does nothing on Mac OS +} + +#endif + +- (CGFloat)offsetForItemAtIndex:(NSInteger)index +{ + //calculate relative position + CGFloat offset = index - _scrollOffset; + if (_wrapEnabled) + { + if (offset > _numberOfItems/2.0) + { + offset -= _numberOfItems; + } + else if (offset < -_numberOfItems/2.0) + { + offset += _numberOfItems; + } + } + +#ifdef ICAROUSEL_MACOS + + if (_vertical) + { + //invert transform + offset = -offset; + } + +#endif + + return offset; +} + +- (UIView *)containView:(UIView *)view +{ + //set item width + if (!_itemWidth) + { + _itemWidth = _vertical? view.bounds.size.height: view.bounds.size.width; + } + + //set container frame + CGRect frame = view.bounds; + frame.size.width = _vertical? frame.size.width: _itemWidth; + frame.size.height = _vertical? _itemWidth: frame.size.height; + UIView *containerView = [[UIView alloc] initWithFrame:frame]; + +#ifdef ICAROUSEL_MACOS + + //clipping works differently on Mac OS + [containerView setBoundsSize:view.frame.size]; + +#endif + + //set view frame + frame = view.frame; + frame.origin.x = (containerView.bounds.size.width - frame.size.width) / 2.0; + frame.origin.y = (containerView.bounds.size.height - frame.size.height) / 2.0; + view.frame = frame; + [containerView addSubview:view]; + containerView.layer.opacity = 0; + + return containerView; +} + +- (void)transformItemView:(UIView *)view atIndex:(NSInteger)index +{ + //calculate offset + CGFloat offset = [self offsetForItemAtIndex:index]; + + //update alpha + view.superview.layer.opacity = [self alphaForItemWithOffset:offset]; + +#ifdef ICAROUSEL_IOS + + //center view + view.superview.center = CGPointMake(self.bounds.size.width/2.0 + _contentOffset.width, + self.bounds.size.height/2.0 + _contentOffset.height); + + //enable/disable interaction + view.superview.userInteractionEnabled = (!_centerItemWhenSelected || index == self.currentItemIndex); + + //account for retina + view.superview.layer.rasterizationScale = [UIScreen mainScreen].scale; + +#else + + //center view + [view.superview setFrameOrigin:NSMakePoint(self.bounds.size.width/2.0 + _contentOffset.width, + self.bounds.size.height/2.0 + _contentOffset.height)]; + view.superview.layer.anchorPoint = CGPointMake(0.5, 0.5); + + //account for retina + view.superview.layer.rasterizationScale = view.window.screen.backingScaleFactor; + +#endif + + //special-case logic for iCarouselTypeCoverFlow2 + CGFloat clampedOffset = MAX(-1.0, MIN(1.0, offset)); + if (_decelerating || (_scrolling && !_dragging && !_didDrag) || (_autoscroll && !_dragging) || + (!_wrapEnabled && (_scrollOffset < 0 || _scrollOffset >= _numberOfItems - 1))) + { + if (offset > 0) + { + _toggle = (offset <= 0.5)? -clampedOffset: (1.0 - clampedOffset); + } + else + { + _toggle = (offset > -0.5)? -clampedOffset: (- 1.0 - clampedOffset); + } + } + + //calculate transform + CATransform3D transform = [self transformForItemViewWithOffset:offset]; + + //transform view + view.superview.layer.transform = transform; + + //backface culling + BOOL showBackfaces = view.layer.doubleSided; + if (showBackfaces) + { + switch (_type) + { + case iCarouselTypeInvertedCylinder: + { + showBackfaces = NO; + break; + } + case iCarouselTypeCoverFlow: + case iCarouselTypeCoverFlow2: + case iCarouselTypeCustom: + case iCarouselTypeCylinder: + case iCarouselTypeRotary: + case iCarouselTypeInvertedRotary: + case iCarouselTypeWheel: + case iCarouselTypeInvertedWheel: + case iCarouselTypeLinear: + case iCarouselTypeTimeMachine: + case iCarouselTypeInvertedTimeMachine: + { + showBackfaces = YES; + break; + } + } + } + showBackfaces = !![self valueForOption:iCarouselOptionShowBackfaces withDefault:showBackfaces]; + + //we can't just set the layer.doubleSided property because it doesn't block interaction + //instead we'll calculate if the view is front-facing based on the transform + view.superview.hidden = !(showBackfaces ?: (transform.m33 > 0.0)); +} + +#ifdef ICAROUSEL_MACOS + +- (void)resizeSubviewsWithOldSize:(__unused NSSize)oldSize +{ + [self pushAnimationState:NO]; + _contentView.frame = self.bounds; + [self layOutItemViews]; + [self popAnimationState]; +} + +#else + +- (void)layoutSubviews +{ + [super layoutSubviews]; + _contentView.frame = self.bounds; + [self layOutItemViews]; +} + +#endif + +- (void)transformItemViews +{ + for (NSNumber *number in _itemViews) + { + NSInteger index = [number integerValue]; + UIView *view = _itemViews[number]; + [self transformItemView:view atIndex:index]; + } +} + +- (void)updateItemWidth +{ + _itemWidth = [_delegate carouselItemWidth:self] ?: _itemWidth; + if (_numberOfItems > 0) + { + if ([_itemViews count] == 0) + { + [self loadViewAtIndex:0]; + } + } + else if (_numberOfPlaceholders > 0) + { + if ([_itemViews count] == 0) + { + [self loadViewAtIndex:-1]; + } + } +} + +- (void)updateNumberOfVisibleItems +{ + //get number of visible items + switch (_type) + { + case iCarouselTypeLinear: + { + //exact number required to fill screen + CGFloat spacing = [self valueForOption:iCarouselOptionSpacing withDefault:1.0]; + CGFloat width = _vertical ? self.bounds.size.height: self.bounds.size.width; + CGFloat itemWidth = _itemWidth * spacing; + _numberOfVisibleItems = ceil(width / itemWidth) + 2; + break; + } + case iCarouselTypeCoverFlow: + case iCarouselTypeCoverFlow2: + { + //exact number required to fill screen + CGFloat spacing = [self valueForOption:iCarouselOptionSpacing withDefault:0.25]; + CGFloat width = _vertical ? self.bounds.size.height: self.bounds.size.width; + CGFloat itemWidth = _itemWidth * spacing; + _numberOfVisibleItems = ceil(width / itemWidth) + 2; + break; + } + case iCarouselTypeRotary: + case iCarouselTypeCylinder: + { + //based on count value + _numberOfVisibleItems = [self circularCarouselItemCount]; + break; + } + case iCarouselTypeInvertedRotary: + case iCarouselTypeInvertedCylinder: + { + //TODO: improve this + _numberOfVisibleItems = ceil([self circularCarouselItemCount] / 2.0); + break; + } + case iCarouselTypeWheel: + case iCarouselTypeInvertedWheel: + { + //TODO: improve this + CGFloat count = [self circularCarouselItemCount]; + CGFloat spacing = [self valueForOption:iCarouselOptionSpacing withDefault:1.0]; + CGFloat arc = [self valueForOption:iCarouselOptionArc withDefault:M_PI * 2.0]; + CGFloat radius = [self valueForOption:iCarouselOptionRadius withDefault:_itemWidth * spacing * count / arc]; + if (radius - _itemWidth / 2.0 < MIN(self.bounds.size.width, self.bounds.size.height) / 2.0) + { + _numberOfVisibleItems = count; + } + else + { + _numberOfVisibleItems = ceil(count / 2.0) + 1; + } + break; + } + case iCarouselTypeTimeMachine: + case iCarouselTypeInvertedTimeMachine: + case iCarouselTypeCustom: + { + //slightly arbitrary number, chosen for performance reasons + _numberOfVisibleItems = MAX_VISIBLE_ITEMS; + break; + } + } + _numberOfVisibleItems = MIN(MAX_VISIBLE_ITEMS, _numberOfVisibleItems); + _numberOfVisibleItems = [self valueForOption:iCarouselOptionVisibleItems withDefault:_numberOfVisibleItems]; + _numberOfVisibleItems = MAX(0, MIN(_numberOfVisibleItems, _numberOfItems + _numberOfPlaceholdersToShow)); + +} + +- (NSInteger)circularCarouselItemCount +{ + NSInteger count = 0; + switch (_type) + { + case iCarouselTypeRotary: + case iCarouselTypeInvertedRotary: + case iCarouselTypeCylinder: + case iCarouselTypeInvertedCylinder: + case iCarouselTypeWheel: + case iCarouselTypeInvertedWheel: + { + //slightly arbitrary number, chosen for aesthetic reasons + CGFloat spacing = [self valueForOption:iCarouselOptionSpacing withDefault:1.0]; + CGFloat width = _vertical ? self.bounds.size.height: self.bounds.size.width; + count = MIN(MAX_VISIBLE_ITEMS, MAX(12, ceil(width / (spacing * _itemWidth)) * M_PI)); + count = MIN(_numberOfItems + _numberOfPlaceholdersToShow, count); + break; + } + case iCarouselTypeCoverFlow: + case iCarouselTypeCoverFlow2: + case iCarouselTypeTimeMachine: + case iCarouselTypeInvertedTimeMachine: + case iCarouselTypeLinear: + case iCarouselTypeCustom: + { + //not used for non-circular carousels + return _numberOfItems + _numberOfPlaceholdersToShow; + } + } + return [self valueForOption:iCarouselOptionCount withDefault:count]; +} + +- (void)layOutItemViews +{ + //bail out if not set up yet + if (!_dataSource || !_contentView) + { + return; + } + + //update wrap + switch (_type) + { + case iCarouselTypeRotary: + case iCarouselTypeInvertedRotary: + case iCarouselTypeCylinder: + case iCarouselTypeInvertedCylinder: + case iCarouselTypeWheel: + case iCarouselTypeInvertedWheel: + { + _wrapEnabled = YES; + break; + } + case iCarouselTypeCoverFlow: + case iCarouselTypeCoverFlow2: + case iCarouselTypeTimeMachine: + case iCarouselTypeInvertedTimeMachine: + case iCarouselTypeLinear: + case iCarouselTypeCustom: + { + _wrapEnabled = NO; + break; + } + } + _wrapEnabled = !![self valueForOption:iCarouselOptionWrap withDefault:_wrapEnabled]; + + //no placeholders on wrapped carousels + _numberOfPlaceholdersToShow = _wrapEnabled? 0: _numberOfPlaceholders; + + //set item width + [self updateItemWidth]; + + //update number of visible items + [self updateNumberOfVisibleItems]; + + //prevent false index changed event + _previousScrollOffset = self.scrollOffset; + + //update offset multiplier + switch (_type) + { + case iCarouselTypeCoverFlow: + case iCarouselTypeCoverFlow2: + { + _offsetMultiplier = 2.0; + break; + } + case iCarouselTypeCylinder: + case iCarouselTypeInvertedCylinder: + case iCarouselTypeWheel: + case iCarouselTypeInvertedWheel: + case iCarouselTypeRotary: + case iCarouselTypeInvertedRotary: + case iCarouselTypeTimeMachine: + case iCarouselTypeInvertedTimeMachine: + case iCarouselTypeLinear: + case iCarouselTypeCustom: + { + _offsetMultiplier = 1.0; + break; + } + } + _offsetMultiplier = [self valueForOption:iCarouselOptionOffsetMultiplier withDefault:_offsetMultiplier]; + + //align + if (!_scrolling && !_decelerating && !_autoscroll) + { + if (_scrollToItemBoundary) + { + [self scrollToItemAtIndex:self.currentItemIndex animated:YES]; + } + else + { + _scrollOffset = [self clampedOffset:_scrollOffset]; + } + } + + //update views + [self didScroll]; +} + + +#pragma mark - +#pragma mark View queing + +- (void)queueItemView:(UIView *)view +{ + if (view) + { + [_itemViewPool addObject:view]; + } +} + +- (void)queuePlaceholderView:(UIView *)view +{ + if (view) + { + [_placeholderViewPool addObject:view]; + } +} + +- (UIView *)dequeueItemView +{ + UIView *view = [_itemViewPool anyObject]; + if (view) + { + [_itemViewPool removeObject:view]; + } + return view; +} + +- (UIView *)dequeuePlaceholderView +{ + UIView *view = [_placeholderViewPool anyObject]; + if (view) + { + [_placeholderViewPool removeObject:view]; + } + return view; +} + + +#pragma mark - +#pragma mark View loading + +- (UIView *)loadViewAtIndex:(NSInteger)index withContainerView:(UIView *)containerView +{ + [self pushAnimationState:NO]; + + UIView *view = nil; + if (index < 0) + { + view = [_dataSource carousel:self placeholderViewAtIndex:(NSInteger)(ceil((CGFloat)_numberOfPlaceholdersToShow/2.0)) + index reusingView:[self dequeuePlaceholderView]]; + } + else if (index >= _numberOfItems) + { + view = [_dataSource carousel:self placeholderViewAtIndex:_numberOfPlaceholdersToShow/2.0 + index - _numberOfItems reusingView:[self dequeuePlaceholderView]]; + } + else + { + view = [_dataSource carousel:self viewForItemAtIndex:index reusingView:[self dequeueItemView]]; + } + + if (view == nil) + { + view = [[UIView alloc] init]; + } + + [self setItemView:view forIndex:index]; + if (containerView) + { + //get old item view + UIView *oldItemView = [containerView.subviews lastObject]; + if (index < 0 || index >= _numberOfItems) + { + [self queuePlaceholderView:oldItemView]; + } + else + { + [self queueItemView:oldItemView]; + } + + //set container frame + CGRect frame = containerView.bounds; + if(_vertical) + { + frame.size.width = view.frame.size.width; + frame.size.height = MIN(_itemWidth, view.frame.size.height); + } + else + { + frame.size.width = MIN(_itemWidth, view.frame.size.width); + frame.size.height = view.frame.size.height; + } + containerView.bounds = frame; + +#ifdef ICAROUSEL_MACOS + + //clipping works differently on Mac OS + [containerView setBoundsSize:view.frame.size]; + +#endif + + //set view frame + frame = view.frame; + frame.origin.x = (containerView.bounds.size.width - frame.size.width) / 2.0; + frame.origin.y = (containerView.bounds.size.height - frame.size.height) / 2.0; + view.frame = frame; + + //switch views + [oldItemView removeFromSuperview]; + [containerView addSubview:view]; + } + else + { + [_contentView addSubview:[self containView:view]]; + } + view.superview.layer.opacity = 0.0; + [self transformItemView:view atIndex:index]; + + [self popAnimationState]; + + return view; +} + +- (UIView *)loadViewAtIndex:(NSInteger)index +{ + return [self loadViewAtIndex:index withContainerView:nil]; +} + +- (void)loadUnloadViews +{ + //set item width + [self updateItemWidth]; + + //update number of visible items + [self updateNumberOfVisibleItems]; + + //calculate visible view indices + NSMutableSet *visibleIndices = [NSMutableSet setWithCapacity:_numberOfVisibleItems]; + NSInteger min = -(NSInteger)(ceil((CGFloat)_numberOfPlaceholdersToShow/2.0)); + NSInteger max = _numberOfItems - 1 + _numberOfPlaceholdersToShow/2; + NSInteger offset = self.currentItemIndex - _numberOfVisibleItems/2; + if (!_wrapEnabled) + { + offset = MAX(min, MIN(max - _numberOfVisibleItems + 1, offset)); + } + for (NSInteger i = 0; i < _numberOfVisibleItems; i++) + { + NSInteger index = i + offset; + if (_wrapEnabled) + { + index = [self clampedIndex:index]; + } + CGFloat alpha = [self alphaForItemWithOffset:[self offsetForItemAtIndex:index]]; + if (alpha) + { + //only add views with alpha > 0 + [visibleIndices addObject:@(index)]; + } + } + + //remove offscreen views + for (NSNumber *number in [_itemViews allKeys]) + { + if (![visibleIndices containsObject:number]) + { + UIView *view = _itemViews[number]; + if ([number integerValue] < 0 || [number integerValue] >= _numberOfItems) + { + [self queuePlaceholderView:view]; + } + else + { + [self queueItemView:view]; + } + [view.superview removeFromSuperview]; + [(NSMutableDictionary *)_itemViews removeObjectForKey:number]; + } + } + + //add onscreen views + for (NSNumber *number in visibleIndices) + { + UIView *view = _itemViews[number]; + if (view == nil) + { + [self loadViewAtIndex:[number integerValue]]; + } + } +} + +- (void)reloadData +{ + //remove old views + for (UIView *view in [_itemViews allValues]) + { + [view.superview removeFromSuperview]; + } + + //bail out if not set up yet + if (!_dataSource || !_contentView) + { + return; + } + + //get number of items and placeholders + _numberOfVisibleItems = 0; + _numberOfItems = [_dataSource numberOfItemsInCarousel:self]; + _numberOfPlaceholders = [_dataSource numberOfPlaceholdersInCarousel:self]; + + //reset view pools + self.itemViews = [NSMutableDictionary dictionary]; + self.itemViewPool = [NSMutableSet set]; + self.placeholderViewPool = [NSMutableSet setWithCapacity:_numberOfPlaceholders]; + + //layout views + [self setNeedsLayout]; + + //fix scroll offset + if (_numberOfItems > 0 && _scrollOffset < 0.0) + { + [self scrollToItemAtIndex:0 animated:(_numberOfPlaceholders > 0)]; + } +} + + +#pragma mark - +#pragma mark Scrolling + +- (NSInteger)clampedIndex:(NSInteger)index +{ + if (_numberOfItems == 0) + { + return -1; + } + else if (_wrapEnabled) + { + return index - floor((CGFloat)index / (CGFloat)_numberOfItems) * _numberOfItems; + } + else + { + return MIN(MAX(0, index), MAX(0, _numberOfItems - 1)); + } +} + +- (CGFloat)clampedOffset:(CGFloat)offset +{ + if (_numberOfItems == 0) + { + return -1.0; + } + else if (_wrapEnabled) + { + return offset - floor(offset / (CGFloat)_numberOfItems) * _numberOfItems; + } + else + { + return MIN(MAX(0.0, offset), MAX(0.0, (CGFloat)_numberOfItems - 1.0)); + } +} + +- (NSInteger)currentItemIndex +{ + return [self clampedIndex:round(_scrollOffset)]; +} + +- (NSInteger)minScrollDistanceFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex +{ + NSInteger directDistance = toIndex - fromIndex; + if (_wrapEnabled) + { + NSInteger wrappedDistance = MIN(toIndex, fromIndex) + _numberOfItems - MAX(toIndex, fromIndex); + if (fromIndex < toIndex) + { + wrappedDistance = -wrappedDistance; + } + return (ABS(directDistance) <= ABS(wrappedDistance))? directDistance: wrappedDistance; + } + return directDistance; +} + +- (CGFloat)minScrollDistanceFromOffset:(CGFloat)fromOffset toOffset:(CGFloat)toOffset +{ + CGFloat directDistance = toOffset - fromOffset; + if (_wrapEnabled) + { + CGFloat wrappedDistance = MIN(toOffset, fromOffset) + _numberOfItems - MAX(toOffset, fromOffset); + if (fromOffset < toOffset) + { + wrappedDistance = -wrappedDistance; + } + return (fabs(directDistance) <= fabs(wrappedDistance))? directDistance: wrappedDistance; + } + return directDistance; +} + +- (void)scrollByOffset:(CGFloat)offset duration:(NSTimeInterval)duration +{ + if (duration > 0.0) + { + _decelerating = NO; + _scrolling = YES; + _startTime = CACurrentMediaTime(); + _startOffset = _scrollOffset; + _scrollDuration = duration; + _endOffset = _startOffset + offset; + if (!_wrapEnabled) + { + _endOffset = [self clampedOffset:_endOffset]; + } + [_delegate carouselWillBeginScrollingAnimation:self]; + [self startAnimation]; + } + else + { + self.scrollOffset += offset; + } +} + +- (void)scrollToOffset:(CGFloat)offset duration:(NSTimeInterval)duration +{ + [self scrollByOffset:[self minScrollDistanceFromOffset:_scrollOffset toOffset:offset] duration:duration]; +} + +- (void)scrollByNumberOfItems:(NSInteger)itemCount duration:(NSTimeInterval)duration +{ + if (duration > 0.0) + { + CGFloat offset = 0.0; + if (itemCount > 0) + { + offset = (floor(_scrollOffset) + itemCount) - _scrollOffset; + } + else if (itemCount < 0) + { + offset = (ceil(_scrollOffset) + itemCount) - _scrollOffset; + } + else + { + offset = round(_scrollOffset) - _scrollOffset; + } + [self scrollByOffset:offset duration:duration]; + } + else + { + self.scrollOffset = [self clampedIndex:_previousItemIndex + itemCount]; + } +} + +- (void)scrollToItemAtIndex:(NSInteger)index duration:(NSTimeInterval)duration +{ + [self scrollToOffset:index duration:duration]; +} + +- (void)scrollToItemAtIndex:(NSInteger)index animated:(BOOL)animated +{ + [self scrollToItemAtIndex:index duration:animated? SCROLL_DURATION: 0]; +} + +- (void)removeItemAtIndex:(NSInteger)index animated:(BOOL)animated +{ + index = [self clampedIndex:index]; + UIView *itemView = [self itemViewAtIndex:index]; + + if (animated) + { + +#ifdef ICAROUSEL_IOS + + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.1]; + [UIView setAnimationDelegate:itemView.superview]; + [UIView setAnimationDidStopSelector:@selector(removeFromSuperview)]; + [self performSelector:@selector(queueItemView:) withObject:itemView afterDelay:0.1]; + itemView.superview.layer.opacity = 0.0; + [UIView commitAnimations]; + + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDelay:0.1]; + [UIView setAnimationDuration:INSERT_DURATION]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(depthSortViews)]; + [self removeViewAtIndex:index]; + _numberOfItems --; + _wrapEnabled = !![self valueForOption:iCarouselOptionWrap withDefault:_wrapEnabled]; + [self updateNumberOfVisibleItems]; + _scrollOffset = self.currentItemIndex; + [self didScroll]; + [UIView commitAnimations]; + +#else + [NSAnimationContext beginGrouping]; + [[NSAnimationContext currentContext] setAllowsImplicitAnimation:YES]; + [CATransaction begin]; + [CATransaction setAnimationDuration:0.1]; + [CATransaction setCompletionBlock:^{ + [self queueItemView:itemView]; + [itemView.superview removeFromSuperview]; + }]; + itemView.superview.layer.opacity = 0.0; + [CATransaction commit]; + + [CATransaction begin]; + [CATransaction setAnimationDuration:INSERT_DURATION]; + [CATransaction setCompletionBlock:^{ + [self depthSortViews]; + }]; + [self removeViewAtIndex:index]; + _numberOfItems --; + _wrapEnabled = !![self valueForOption:iCarouselOptionWrap withDefault:_wrapEnabled]; + _scrollOffset = self.currentItemIndex; + [self didScroll]; + [CATransaction commit]; + [NSAnimationContext endGrouping]; +#endif + + } + else + { + [self pushAnimationState:NO]; + [self queueItemView:itemView]; + [itemView.superview removeFromSuperview]; + [self removeViewAtIndex:index]; + _numberOfItems --; + _wrapEnabled = !![self valueForOption:iCarouselOptionWrap withDefault:_wrapEnabled]; + _scrollOffset = self.currentItemIndex; + [self didScroll]; + [self depthSortViews]; + [self popAnimationState]; + } +} + +- (void)insertItemAtIndex:(NSInteger)index animated:(BOOL)animated +{ + _numberOfItems ++; + _wrapEnabled = !![self valueForOption:iCarouselOptionWrap withDefault:_wrapEnabled]; + [self updateNumberOfVisibleItems]; + + index = [self clampedIndex:index]; + [self insertView:nil atIndex:index]; + [self loadViewAtIndex:index]; + + if (fabs(_itemWidth) < FLOAT_ERROR_MARGIN) + { + [self updateItemWidth]; + } + + if (animated) + { + +#ifdef ICAROUSEL_IOS + + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:INSERT_DURATION]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(didScroll)]; + [self transformItemViews]; + [UIView commitAnimations]; + +#else + [NSAnimationContext beginGrouping]; + [[NSAnimationContext currentContext] setAllowsImplicitAnimation:YES]; + [CATransaction begin]; + [CATransaction setAnimationDuration:INSERT_DURATION]; + [CATransaction setCompletionBlock:^{ + [self didScroll]; + }]; + [self transformItemViews]; + [CATransaction commit]; + [NSAnimationContext endGrouping]; +#endif + + } + else + { + [self pushAnimationState:NO]; + [self didScroll]; + [self popAnimationState]; + } + + if (_scrollOffset < 0.0) + { + [self scrollToItemAtIndex:0 animated:(animated && _numberOfPlaceholders)]; + } +} + +- (void)reloadItemAtIndex:(NSInteger)index animated:(BOOL)animated +{ + //get container view + UIView *containerView = [[self itemViewAtIndex:index] superview]; + if (containerView) + { + if (animated) + { + //fade transition + CATransition *transition = [CATransition animation]; + transition.duration = INSERT_DURATION; + transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + transition.type = kCATransitionFade; + [containerView.layer addAnimation:transition forKey:nil]; + } + + //reload view + [self loadViewAtIndex:index withContainerView:containerView]; + } +} + +#pragma mark - +#pragma mark Animation + +- (void)startAnimation +{ + if (!_timer) + { + self.timer = [NSTimer timerWithTimeInterval:1.0/60.0 + target:self + selector:@selector(step) + userInfo:nil + repeats:YES]; + + [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode]; + +#ifdef ICAROUSEL_IOS + + [[NSRunLoop mainRunLoop] addTimer:_timer forMode:UITrackingRunLoopMode]; + +#endif + + } +} + +- (void)stopAnimation +{ + [_timer invalidate]; + _timer = nil; +} + +- (CGFloat)decelerationDistance +{ + CGFloat acceleration = -_startVelocity * DECELERATION_MULTIPLIER * (1.0 - _decelerationRate); + return -pow(_startVelocity, 2.0) / (2.0 * acceleration); +} + +- (BOOL)shouldDecelerate +{ + return (fabs(_startVelocity) > SCROLL_SPEED_THRESHOLD) && + (fabs([self decelerationDistance]) > DECELERATE_THRESHOLD); +} + +- (BOOL)shouldScroll +{ + return (fabs(_startVelocity) > SCROLL_SPEED_THRESHOLD) && + (fabs(_scrollOffset - self.currentItemIndex) > SCROLL_DISTANCE_THRESHOLD); +} + +- (void)startDecelerating +{ + CGFloat distance = [self decelerationDistance]; + _startOffset = _scrollOffset; + _endOffset = _startOffset + distance; + if (_pagingEnabled) + { + if (distance > 0.0) + { + _endOffset = ceil(_startOffset); + } + else + { + _endOffset = floor(_startOffset); + } + } + else if (_stopAtItemBoundary) + { + if (distance > 0.0) + { + _endOffset = ceil(_endOffset); + } + else + { + _endOffset = floor(_endOffset); + } + } + if (!_wrapEnabled) + { + if (_bounces) + { + _endOffset = MAX(-_bounceDistance, MIN(_numberOfItems - 1.0 + _bounceDistance, _endOffset)); + } + else + { + _endOffset = [self clampedOffset:_endOffset]; + } + } + distance = _endOffset - _startOffset; + + _startTime = CACurrentMediaTime(); + _scrollDuration = fabs(distance) / fabs(0.5 * _startVelocity); + + if (distance != 0.0) + { + _decelerating = YES; + [self startAnimation]; + } +} + +- (CGFloat)easeInOut:(CGFloat)time +{ + return (time < 0.5)? 0.5 * pow(time * 2.0, 3.0): 0.5 * pow(time * 2.0 - 2.0, 3.0) + 1.0; +} + +- (void)step +{ + [self pushAnimationState:NO]; + NSTimeInterval currentTime = CACurrentMediaTime(); + double delta = currentTime - _lastTime; + _lastTime = currentTime; + + if (_scrolling && !_dragging) + { + NSTimeInterval time = MIN(1.0, (currentTime - _startTime) / _scrollDuration); + delta = [self easeInOut:time]; + _scrollOffset = _startOffset + (_endOffset - _startOffset) * delta; + [self didScroll]; + if (time >= 1.0) + { + _scrolling = NO; + [self depthSortViews]; + [self pushAnimationState:YES]; + [_delegate carouselDidEndScrollingAnimation:self]; + [self popAnimationState]; + } + } + else if (_decelerating) + { + CGFloat time = MIN(_scrollDuration, currentTime - _startTime); + CGFloat acceleration = -_startVelocity/_scrollDuration; + CGFloat distance = _startVelocity * time + 0.5 * acceleration * pow(time, 2.0); + _scrollOffset = _startOffset + distance; + [self didScroll]; + if (fabs(time - _scrollDuration) < FLOAT_ERROR_MARGIN) + { + _decelerating = NO; + [self pushAnimationState:YES]; + [_delegate carouselDidEndDecelerating:self]; + [self popAnimationState]; + if ((_scrollToItemBoundary || fabs(_scrollOffset - [self clampedOffset:_scrollOffset]) > FLOAT_ERROR_MARGIN) && !_autoscroll) + { + if (fabs(_scrollOffset - self.currentItemIndex) < FLOAT_ERROR_MARGIN) + { + //call scroll to trigger events for legacy support reasons + //even though technically we don't need to scroll at all + [self scrollToItemAtIndex:self.currentItemIndex duration:0.01]; + } + else + { + [self scrollToItemAtIndex:self.currentItemIndex animated:YES]; + } + } + else + { + CGFloat difference = round(_scrollOffset) - _scrollOffset; + if (difference > 0.5) + { + difference = difference - 1.0; + } + else if (difference < -0.5) + { + difference = 1.0 + difference; + } + _toggleTime = currentTime - MAX_TOGGLE_DURATION * fabs(difference); + _toggle = MAX(-1.0, MIN(1.0, -difference)); + } + } + } + else if (_autoscroll && !_dragging) + { + //autoscroll goes backwards from what you'd expect, for historical reasons + self.scrollOffset = [self clampedOffset:_scrollOffset - delta * _autoscroll]; + } + else if (fabs(_toggle) > FLOAT_ERROR_MARGIN) + { + NSTimeInterval toggleDuration = _startVelocity? MIN(1.0, MAX(0.0, 1.0 / fabs(_startVelocity))): 1.0; + toggleDuration = MIN_TOGGLE_DURATION + (MAX_TOGGLE_DURATION - MIN_TOGGLE_DURATION) * toggleDuration; + NSTimeInterval time = MIN(1.0, (currentTime - _toggleTime) / toggleDuration); + delta = [self easeInOut:time]; + _toggle = (_toggle < 0.0)? (delta - 1.0): (1.0 - delta); + [self didScroll]; + } + else if (!_autoscroll) + { + [self stopAnimation]; + } + + [self popAnimationState]; +} + +#ifdef ICAROUSEL_IOS + +- (void)didMoveToSuperview + +#else + +- (void)viewDidMoveToSuperview + +#endif + +{ + if (self.superview) + { + [self startAnimation]; + } + else + { + [self stopAnimation]; + } +} + +- (void)didScroll +{ + if (_wrapEnabled || !_bounces) + { + _scrollOffset = [self clampedOffset:_scrollOffset]; + } + else + { + CGFloat min = -_bounceDistance; + CGFloat max = MAX(_numberOfItems - 1, 0.0) + _bounceDistance; + if (_scrollOffset < min) + { + _scrollOffset = min; + _startVelocity = 0.0; + } + else if (_scrollOffset > max) + { + _scrollOffset = max; + _startVelocity = 0.0; + } + } + + //check if index has changed + NSInteger difference = [self minScrollDistanceFromIndex:self.currentItemIndex toIndex:self.previousItemIndex]; + if (difference) + { + _toggleTime = CACurrentMediaTime(); + _toggle = MAX(-1, MIN(1, difference)); + +#ifdef ICAROUSEL_MACOS + + if (_vertical) + { + //invert toggle + _toggle = -_toggle; + } + +#endif + + [self startAnimation]; + } + + [self loadUnloadViews]; + [self transformItemViews]; + + //notify delegate of offset change + if (fabs(_scrollOffset - _previousScrollOffset) > FLOAT_ERROR_MARGIN) + { + [self pushAnimationState:YES]; + [_delegate carouselDidScroll:self]; + [self popAnimationState]; + } + + //notify delegate of index change + if (_previousItemIndex != self.currentItemIndex) + { + [self pushAnimationState:YES]; + [_delegate carouselCurrentItemIndexDidChange:self]; + [self popAnimationState]; + } + + //update previous index + _previousScrollOffset = _scrollOffset; + _previousItemIndex = self.currentItemIndex; +} + + +#ifdef ICAROUSEL_IOS + + +#pragma mark - +#pragma mark Gestures and taps + +- (NSInteger)viewOrSuperviewIndex:(UIView *)view +{ + if (view == nil || view == _contentView) + { + return NSNotFound; + } + NSInteger index = [self indexOfItemView:view]; + if (index == NSNotFound) + { + return [self viewOrSuperviewIndex:view.superview]; + } + return index; +} + +- (BOOL)viewOrSuperview:(UIView *)view implementsSelector:(SEL)selector +{ + if (!view || view == self.contentView) + { + return NO; + } + + //thanks to @mattjgalloway and @shaps for idea + //https://gist.github.com/mattjgalloway/6279363 + //https://gist.github.com/shaps80/6279008 + + Class viewClass = [view class]; + while (viewClass && viewClass != [UIView class]) + { + unsigned int numberOfMethods; + Method *methods = class_copyMethodList(viewClass, &numberOfMethods); + for (unsigned int i = 0; i < numberOfMethods; i++) + { + if (method_getName(methods[i]) == selector) + { + free(methods); + return YES; + } + } + if (methods) free(methods); + viewClass = [viewClass superclass]; + } + + return [self viewOrSuperview:view.superview implementsSelector:selector]; +} + +- (id)viewOrSuperview:(UIView *)view ofClass:(Class)class +{ + if (!view || view == self.contentView) + { + return nil; + } + else if ([view isKindOfClass:class]) + { + return view; + } + return [self viewOrSuperview:view.superview ofClass:class]; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gesture shouldReceiveTouch:(UITouch *)touch +{ + if (_scrollEnabled) + { + _dragging = NO; + _scrolling = NO; + _decelerating = NO; + } + + if ([gesture isKindOfClass:[UITapGestureRecognizer class]]) + { + //handle tap + NSInteger index = [self viewOrSuperviewIndex:touch.view]; + if (index == NSNotFound && _centerItemWhenSelected) + { + //view is a container view + index = [self viewOrSuperviewIndex:[touch.view.subviews lastObject]]; + } + if (index != NSNotFound) + { + if ([self viewOrSuperview:touch.view implementsSelector:@selector(touchesBegan:withEvent:)]) + { + return NO; + } + } + } + else if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) + { + if (!_scrollEnabled) + { + return NO; + } + else if ([self viewOrSuperview:touch.view implementsSelector:@selector(touchesMoved:withEvent:)]) + { + UIScrollView *scrollView = [self viewOrSuperview:touch.view ofClass:[UIScrollView class]]; + if (scrollView) + { + return !scrollView.scrollEnabled || + (self.vertical && scrollView.contentSize.height <= scrollView.frame.size.height) || + (!self.vertical && scrollView.contentSize.width <= scrollView.frame.size.width); + } + if ([self viewOrSuperview:touch.view ofClass:[UIButton class]] || + [self viewOrSuperview:touch.view ofClass:[UIBarButtonItem class]]) + { + return YES; + } + return NO; + } + } + return YES; +} + +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gesture +{ + if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) + { + //ignore vertical swipes + UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *)gesture; + CGPoint translation = [panGesture translationInView:self]; + if (_ignorePerpendicularSwipes) + { + if (_vertical) + { + return fabs(translation.x) <= fabs(translation.y); + } + else + { + return fabs(translation.x) >= fabs(translation.y); + } + } + } + return YES; +} + +- (void)didTap:(UITapGestureRecognizer *)tapGesture +{ + //check for tapped view + NSInteger index = [self indexOfItemView:[self itemViewAtPoint:[tapGesture locationInView:_contentView]]]; + if (index != NSNotFound) + { + if (!_delegate || [_delegate carousel:self shouldSelectItemAtIndex:index]) + { + if ((index != self.currentItemIndex && _centerItemWhenSelected) || + (index == self.currentItemIndex && _scrollToItemBoundary)) + { + [self scrollToItemAtIndex:index animated:YES]; + } + [_delegate carousel:self didSelectItemAtIndex:index]; + } + else if (_scrollEnabled && _scrollToItemBoundary && _autoscroll) + { + [self scrollToItemAtIndex:self.currentItemIndex animated:YES]; + } + } +} + +- (void)didPan:(UIPanGestureRecognizer *)panGesture +{ + if (_scrollEnabled && _numberOfItems) + { + switch (panGesture.state) + { + case UIGestureRecognizerStateBegan: + { + _dragging = YES; + _scrolling = NO; + _decelerating = NO; + _previousTranslation = _vertical? [panGesture translationInView:self].y: [panGesture translationInView:self].x; + [_delegate carouselWillBeginDragging:self]; + break; + } + case UIGestureRecognizerStateEnded: + case UIGestureRecognizerStateCancelled: + case UIGestureRecognizerStateFailed: + { + _dragging = NO; + _didDrag = YES; + if ([self shouldDecelerate]) + { + _didDrag = NO; + [self startDecelerating]; + } + + [self pushAnimationState:YES]; + [_delegate carouselDidEndDragging:self willDecelerate:_decelerating]; + [self popAnimationState]; + + if (!_decelerating) + { + if ((_scrollToItemBoundary || fabs(_scrollOffset - [self clampedOffset:_scrollOffset]) > FLOAT_ERROR_MARGIN) && !_autoscroll) + { + if (fabs(_scrollOffset - self.currentItemIndex) < FLOAT_ERROR_MARGIN) + { + //call scroll to trigger events for legacy support reasons + //even though technically we don't need to scroll at all + [self scrollToItemAtIndex:self.currentItemIndex duration:0.01]; + } + else if ([self shouldScroll]) + { + NSInteger direction = (int)(_startVelocity / fabs(_startVelocity)); + [self scrollToItemAtIndex:self.currentItemIndex + direction animated:YES]; + } + else + { + [self scrollToItemAtIndex:self.currentItemIndex animated:YES]; + } + } + else + { + [self depthSortViews]; + } + } + else + { + [self pushAnimationState:YES]; + [_delegate carouselWillBeginDecelerating:self]; + [self popAnimationState]; + } + break; + } + case UIGestureRecognizerStateChanged: + { + CGFloat translation = (_vertical? [panGesture translationInView:self].y: [panGesture translationInView:self].x) - _previousTranslation; + CGFloat factor = 1.0; + if (!_wrapEnabled && _bounces) + { + factor = 1.0 - MIN(fabs(_scrollOffset - [self clampedOffset:_scrollOffset]), _bounceDistance) / _bounceDistance; + } + + _previousTranslation = _vertical? [panGesture translationInView:self].y: [panGesture translationInView:self].x; + _startVelocity = -(_vertical? [panGesture velocityInView:self].y: [panGesture velocityInView:self].x) * factor * _scrollSpeed / _itemWidth; + _scrollOffset -= translation * factor * _offsetMultiplier / _itemWidth; + [self didScroll]; + break; + } + case UIGestureRecognizerStatePossible: + { + //do nothing + break; + } + } + } +} + +#else + + +#pragma mark - +#pragma mark Mouse control + +- (void)mouseDown:(__unused NSEvent *)theEvent +{ + _didDrag = NO; + _startVelocity = 0.0; +} + +- (void)mouseDragged:(NSEvent *)theEvent +{ + _didDrag = YES; + if (_scrollEnabled) + { + if (!_dragging) + { + _dragging = YES; + [_delegate carouselWillBeginDragging:self]; + } + _scrolling = NO; + _decelerating = NO; + + CGFloat translation = _vertical? [theEvent deltaY]: [theEvent deltaX]; + CGFloat factor = 1.0; + if (!_wrapEnabled && _bounces) + { + factor = 1.0 - MIN(fabs(_scrollOffset - [self clampedOffset:_scrollOffset]), _bounceDistance) / _bounceDistance; + } + + NSTimeInterval thisTime = [theEvent timestamp]; + _startVelocity = -(translation / (thisTime - _startTime)) * factor * _scrollSpeed / _itemWidth; + _startTime = thisTime; + + _scrollOffset -= translation * factor * _offsetMultiplier / _itemWidth; + [self pushAnimationState:NO]; + [self didScroll]; + [self popAnimationState]; + } +} + +- (void)mouseUp:(NSEvent *)theEvent +{ + if (!_didDrag) + { + //convert position to view + CGPoint position = [theEvent locationInWindow]; + position = [self convertPoint:position fromView:self.window.contentView]; + + //check for tapped view + NSInteger index = [self indexOfItemView:[self itemViewAtPoint:position]]; + if (index != NSNotFound) + { + if (_centerItemWhenSelected && index != self.currentItemIndex) + { + [self scrollToItemAtIndex:index animated:YES]; + } + if (!_delegate || [_delegate carousel:self shouldSelectItemAtIndex:index]) + { + [self pushAnimationState:YES]; + [_delegate carousel:self didSelectItemAtIndex:index]; + [self popAnimationState]; + } + } + } + else if (_scrollEnabled) + { + _dragging = NO; + if ([self shouldDecelerate]) + { + _didDrag = NO; + [self startDecelerating]; + } + + [self pushAnimationState:YES]; + [_delegate carouselDidEndDragging:self willDecelerate:_decelerating]; + [self popAnimationState]; + + if (!_decelerating && !_autoscroll) + { + if ([self shouldScroll]) + { + NSInteger direction = (int)(_startVelocity / fabs(_startVelocity)); + [self scrollToItemAtIndex:self.currentItemIndex + direction animated:YES]; + } + else + { + [self scrollToItemAtIndex:self.currentItemIndex animated:YES]; + } + } + else + { + [self pushAnimationState:YES]; + [_delegate carouselWillBeginDecelerating:self]; + [self popAnimationState]; + } + } +} + + +#pragma mark - +#pragma mark Keyboard control + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +- (void)keyDown:(NSEvent *)theEvent +{ + NSString *characters = [theEvent charactersIgnoringModifiers]; + if (_scrollEnabled && !_scrolling && [characters length]) + { + if (_vertical) + { + switch ([characters characterAtIndex:0]) + { + case NSUpArrowFunctionKey: + { + [self scrollToItemAtIndex:self.currentItemIndex-1 animated:YES]; + break; + } + case NSDownArrowFunctionKey: + { + [self scrollToItemAtIndex:self.currentItemIndex+1 animated:YES]; + break; + } + } + } + else + { + switch ([characters characterAtIndex:0]) + { + case NSLeftArrowFunctionKey: + { + [self scrollToItemAtIndex:self.currentItemIndex-1 animated:YES]; + break; + } + case NSRightArrowFunctionKey: + { + [self scrollToItemAtIndex:self.currentItemIndex+1 animated:YES]; + break; + } + } + } + } +} + +#endif + +@end