Skip to content

Commit

Permalink
- Added icon
Browse files Browse the repository at this point in the history
- Added README
- Added license
  • Loading branch information
mtabini committed Oct 15, 2010
1 parent 8d68ed3 commit 14e2a96
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 8,163 deletions.
18 changes: 9 additions & 9 deletions AFKPageFlipper-Info.plist
Expand Up @@ -5,11 +5,11 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<string>Flipper</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<string>Icon.png</string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
Expand All @@ -26,12 +26,12 @@
<true/>
<key>NSMainNibFile</key>
<string>MainWindow</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
8,201 changes: 75 additions & 8,126 deletions AFKPageFlipper.xcodeproj/marcot.pbxuser

Large diffs are not rendered by default.

56 changes: 29 additions & 27 deletions AFKPageFlipper.xcodeproj/marcot.perspectivev3
Expand Up @@ -231,6 +231,8 @@
<key>Layout</key>
<array>
<dict>
<key>BecomeActive</key>
<true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXBottomSmartGroupGIDs</key>
Expand Down Expand Up @@ -279,7 +281,10 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>33</integer>
<integer>3</integer>
<integer>2</integer>
<integer>1</integer>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
Expand Down Expand Up @@ -311,26 +316,24 @@
<key>Dock</key>
<array>
<dict>
<key>BecomeActive</key>
<true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>8FBAC1921263F96A00881579</string>
<key>PBXProjectModuleLabel</key>
<string>AFKPageFlipper.m</string>
<string>AFKPageFlipper.h</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>8FBAC1931263F96A00881579</string>
<key>PBXProjectModuleLabel</key>
<string>AFKPageFlipper.m</string>
<string>AFKPageFlipper.h</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>8FAEF9B01267F13000D88B84</string>
<string>8FA87C4B1267FE0100089D6E</string>
<key>history</key>
<array>
<string>8FBAC1B61263FAD100881579</string>
Expand All @@ -341,8 +344,9 @@
<string>8FAEF3E91266C4C400D88B84</string>
<string>8FAEF47D1266CA2400D88B84</string>
<string>8FAEF47E1266CA2400D88B84</string>
<string>8FAEF9B81267F98A00D88B84</string>
<string>8FA87C4A1267FE0100089D6E</string>
<string>8FAEF9671267E1E700D88B84</string>
<string>8FAEF9A61267E95900D88B84</string>
</array>
</dict>
<key>SplitCount</key>
Expand Down Expand Up @@ -382,6 +386,8 @@
<dict>
<key>Frame</key>
<string>{{10, 27}, {1713, -27}}</string>
<key>RubberWindowFrame</key>
<string>0 59 1920 1119 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>XCDetailModule</string>
Expand All @@ -397,9 +403,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {1713, -27}}</string>
<key>RubberWindowFrame</key>
<string>0 59 1920 1119 0 0 1920 1178 </string>
<string>{{0, 0}, {614, 336}}</string>
</dict>
<key>Module</key>
<string>PBXProjectFindModule</string>
Expand Down Expand Up @@ -465,11 +469,11 @@
</array>
<key>TableOfContents</key>
<array>
<string>8FAEF18B1266AF5F00D88B84</string>
<string>8FA87C4C1267FE0100089D6E</string>
<string>1CA23ED40692098700951B8B</string>
<string>8FAEF18C1266AF5F00D88B84</string>
<string>8FA87C4D1267FE0100089D6E</string>
<string>8FBAC1921263F96A00881579</string>
<string>8FAEF18D1266AF5F00D88B84</string>
<string>8FA87C4E1267FE0100089D6E</string>
<string>1CA23EDF0692099D00951B8B</string>
<string>1CA23EE00692099D00951B8B</string>
<string>1CA23EE10692099D00951B8B</string>
Expand Down Expand Up @@ -660,10 +664,6 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
<string>8FAEF9B11267F13000D88B84</string>
<string>8FAEF3CC1266C32100D88B84</string>
<string>8FAEF1951266AF5F00D88B84</string>
<string>8FAEF1961266AF5F00D88B84</string>
<string>/Users/marcot/Documents/XCode/AFKPageFlipper/AFKPageFlipper.xcodeproj</string>
</array>
<key>WindowString</key>
Expand Down Expand Up @@ -993,16 +993,18 @@
<string>Yes</string>
</dict>
<dict>
<key>FirstTimeWindowDisplayed</key>
<false/>
<key>Identifier</key>
<string>windowTool.debuggerConsole</string>
<key>IsVertical</key>
<true/>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>BecomeActive</key>
<integer>1</integer>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
Expand All @@ -1013,18 +1015,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {700, 358}}</string>
<string>{{0, 0}, {440, 359}}</string>
<key>RubberWindowFrame</key>
<string>149 87 700 400 0 0 1440 878 </string>
<string>21 755 440 400 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXDebugCLIModule</string>
<key>Proportion</key>
<string>358pt</string>
<string>359pt</string>
</dict>
</array>
<key>Proportion</key>
<string>358pt</string>
<string>359pt</string>
</dict>
</array>
<key>Name</key>
Expand All @@ -1034,21 +1036,21 @@
<string>PBXDebugCLIModule</string>
</array>
<key>StatusbarIsVisible</key>
<integer>1</integer>
<true/>
<key>TableOfContents</key>
<array>
<string>1C530D5B069F1CE1000CFCEE</string>
<string>1C530D5C069F1CE1000CFCEE</string>
<string>8FAEF9BB1267F98A00D88B84</string>
<string>1C78EAAC065D492600B07095</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.consoleV3</string>
<key>WindowString</key>
<string>149 87 440 400 0 0 1440 878 </string>
<string>21 755 440 400 0 0 1920 1178 </string>
<key>WindowToolGUID</key>
<string>1C530D5B069F1CE1000CFCEE</string>
<key>WindowToolIsVisible</key>
<integer>0</integer>
<false/>
</dict>
<dict>
<key>Identifier</key>
Expand Down
4 changes: 4 additions & 0 deletions AFKPageFlipper.xcodeproj/project.pbxproj
Expand Up @@ -13,6 +13,7 @@
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; };
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; };
8FAEF9B51267F95A00D88B84 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8FAEF9B41267F95A00D88B84 /* Icon.png */; };
8FBAC19B1263F97A00881579 /* ccrf.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 8FBAC19A1263F97A00881579 /* ccrf.pdf */; };
8FBAC1A41263F99800881579 /* PDFRendererView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FBAC1A31263F99800881579 /* PDFRendererView.m */; };
8FBAC1A81263F9ED00881579 /* MainController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FBAC1A71263F9ED00881579 /* MainController.m */; };
Expand All @@ -31,6 +32,7 @@
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
32CA4F630368D1EE00C91783 /* AFKPageFlipper_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFKPageFlipper_Prefix.pch; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* AFKPageFlipper-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "AFKPageFlipper-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
8FAEF9B41267F95A00D88B84 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Images/Icon.png; sourceTree = "<group>"; };
8FBAC19A1263F97A00881579 /* ccrf.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = ccrf.pdf; sourceTree = "<group>"; };
8FBAC1A21263F99800881579 /* PDFRendererView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDFRendererView.h; sourceTree = "<group>"; };
8FBAC1A31263F99800881579 /* PDFRendererView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDFRendererView.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -99,6 +101,7 @@
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
8FAEF9B41267F95A00D88B84 /* Icon.png */,
8FBAC19A1263F97A00881579 /* ccrf.pdf */,
28AD733E0D9D9553002E5188 /* MainWindow.xib */,
8D1107310486CEB800E47090 /* AFKPageFlipper-Info.plist */,
Expand Down Expand Up @@ -204,6 +207,7 @@
files = (
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */,
8FBAC19B1263F97A00881579 /* ccrf.pdf in Resources */,
8FAEF9B51267F95A00D88B84 /* Icon.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Binary file added Images/Icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions LICENSE
@@ -0,0 +1,12 @@
Copyright (c) 2010, AFK Studio
All rights reserved.

Except as noted below, redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of AFK Studio nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


NOTE: The AFK Studio name and logo and the Flipper icon are trademarks of AFK Studio and cannot be used or reused without AFK Studio's written permission.
53 changes: 52 additions & 1 deletion README.markdown
@@ -1,4 +1,55 @@
AFKPageFlipper
==============

Currently under construction. Come back later!
AFKPageFlipper is a UIView subclass that can be used to display multiple views using a 3-D page flipping mechanism similar to flipping pages in a book. The class supports both direct (by setting a property) and touch-based view transitions in both directions. The touch-based interface supports tap-to-flip on either side of the screen, and pan-to-flip in either direction from anywhere on the screen. The pan functionality is inertial, which means that the user can also swipe to flip between pages.

Each subview that needs to be shown by the subview can contain any arbitrary content (including animated subviews, UI controls, and so on, although those are frozen while switching between pages for performance reasons). Subviews are requested using a just-in-time algorithm to conserve resources (especially memory). In addition, AFKPageFlipper supports less-than-fullscreen rendering—in fact, you can have multiple instances displayed on the same screen (although, to be honest, I can't imagine why you'd need them).

AFKPageFlipper has no external dependencies, with the exception of Quartz Core. The flipping functionality can be added to your project by simply importing two files: AFKPageFlipper.h and AFKPageFlipper.m.

You can see AFKPageFlipper in action [http://screencast.com/t/0vo8rdGZ](here). Please note that the poor frame rate is due to the recording software, and not to the performance of the class. On either the actual simulator or a physical iPad or iPhone, the class is capable of performing full-screen transitions in both landscape and portrait at 60fps without any problems that I've been able to detect.


Usage
-----

Using AFKPageFlipper is extremely simple. Generally speaking, you will need to perform these steps:

* Include AFKPageFlipper.h and AFKPageFlipper.m in your project. These are the only classes you will need.
* Import the Quartz Core framework into your project
* Create an instance of AFKPageFlipper (either programmatically or through Interface Builder) and add it to your window (or to an existing view)
* Provide the instance with a data source
* Optionally, switch programmatically to a specific page

That's it! In most cases, AFKPageFlipper will only require ten lines of actual code or less in order to be added to your project. It's actually easier to use than a UIScrollView, because all the memory management is already handled for you.


Providing a data source
-----------------------

AFKPageFlipper needs a data source from which it can (a) determine how many subviews needs visualizing and (b) fetch the individual subviews as it needs them. It's the developer's job to provide an object that can perform these operations.

The data source (which can be set by changing the dataSource property of an AFKPageFlipper instance) must implement the AFKPageFlipperDataSource formal protocol, which requires it to implement two methods:

* -numberOfPagesForPageFlipper: returns the number of pages to be displayed. Note that zero is not a valid page count (you should hide the view instead).
* -viewForPage:inFlipper: returns the particular view to be displayed in the flipper for a given page number. **Note that page numbers start at 1 and not 0,** and that it's up to you set the frame of the view properly (the flipper passes a pointer to itself to the method call so that you can determine its bounds and use them in your calculations).


Changing pages programmatically
-------------------------------

There are two ways to change the current page programmatically. The first is to set the currentPage property of an AFKPageFlipper instance; this results in a cross-fade from the current page (if any) to the new page. Please note that the class only makes basic data integrity checks: passing a page number that's higher than the maximum number of pages or less than one may result in undefined behaviour.

If you prefer to use the flip transition when changing pages programmatically, you can use the -setCurrentPage:animated: method instead. Passing YES as the value of *animated* will result in the page change to occur through a flip transition. Passing NO will result in a cross-fade.


A note on orientation
---------------------

AFKPageFlipper is orientation aware—but only in the sense that, upon sensing a change in its frame property, it will re-request the number of pages to be displayed from the data source. This is to give you an opportunity to refresh your pages in the event that a different number of views can be displayed in either orientation (for example, a simple book reader like the one implemented as a test for this project could display two pages at a time in landscape, but only one in portrait, which would mean that there are roughly twice as many pages in the latter orientation than in the former).


The sample project
------------------

AFKPageFlipper comes as part of a sample project that implements a simplistic PDF viewer. Most of the code is there as scaffolding to make the PDF rendering possible; if you want to see how AFKPageFlipper is used in practice, you can take a look at MainController.m, where you'll find both the data source implementation and the view-loading mechanism (all of eight lines of code!).

0 comments on commit 14e2a96

Please sign in to comment.