Added KLCircleViewController as part of this repot

This commit is contained in:
Kieran Lafferty
2013-08-06 20:44:41 -04:00
parent c7d519f8cf
commit 9434a1e21d
12 changed files with 1711 additions and 0 deletions

View File

@@ -0,0 +1,420 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
773DA3E6179E461900E75388 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 773DA3E5179E461900E75388 /* Foundation.framework */; };
773DA3EB179E461900E75388 /* KLCircleViewController.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 773DA3EA179E461900E75388 /* KLCircleViewController.h */; };
773DA3ED179E461900E75388 /* KLCircleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 773DA3EC179E461900E75388 /* KLCircleViewController.m */; };
773DA3F5179E461900E75388 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 773DA3F4179E461900E75388 /* SenTestingKit.framework */; };
773DA3F8179E461900E75388 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 773DA3E5179E461900E75388 /* Foundation.framework */; };
773DA3FB179E461900E75388 /* libKLCircleViewController.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 773DA3E2179E461900E75388 /* libKLCircleViewController.a */; };
773DA401179E461900E75388 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 773DA3FF179E461900E75388 /* InfoPlist.strings */; };
773DA404179E461900E75388 /* KLCircleViewControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 773DA403179E461900E75388 /* KLCircleViewControllerTests.m */; };
778057C217B1CAE600D0BBDB /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 778057C117B1CAE600D0BBDB /* UIKit.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
773DA3F9179E461900E75388 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 773DA3DA179E461900E75388 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 773DA3E1179E461900E75388;
remoteInfo = KLCircleViewController;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
773DA3E0179E461900E75388 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/${PRODUCT_NAME}";
dstSubfolderSpec = 16;
files = (
773DA3EB179E461900E75388 /* KLCircleViewController.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
773DA3E2179E461900E75388 /* libKLCircleViewController.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKLCircleViewController.a; sourceTree = BUILT_PRODUCTS_DIR; };
773DA3E5179E461900E75388 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
773DA3E9179E461900E75388 /* KLCircleViewController-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "KLCircleViewController-Prefix.pch"; sourceTree = "<group>"; };
773DA3EA179E461900E75388 /* KLCircleViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KLCircleViewController.h; sourceTree = "<group>"; };
773DA3EC179E461900E75388 /* KLCircleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KLCircleViewController.m; sourceTree = "<group>"; };
773DA3F3179E461900E75388 /* KLCircleViewControllerTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KLCircleViewControllerTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
773DA3F4179E461900E75388 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
773DA3FE179E461900E75388 /* KLCircleViewControllerTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "KLCircleViewControllerTests-Info.plist"; sourceTree = "<group>"; };
773DA400179E461900E75388 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
773DA402179E461900E75388 /* KLCircleViewControllerTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KLCircleViewControllerTests.h; sourceTree = "<group>"; };
773DA403179E461900E75388 /* KLCircleViewControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KLCircleViewControllerTests.m; sourceTree = "<group>"; };
778057C117B1CAE600D0BBDB /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
773DA3DF179E461900E75388 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
778057C217B1CAE600D0BBDB /* UIKit.framework in Frameworks */,
773DA3E6179E461900E75388 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
773DA3EF179E461900E75388 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
773DA3F5179E461900E75388 /* SenTestingKit.framework in Frameworks */,
773DA3F8179E461900E75388 /* Foundation.framework in Frameworks */,
773DA3FB179E461900E75388 /* libKLCircleViewController.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
773DA3D9179E461900E75388 = {
isa = PBXGroup;
children = (
773DA3E7179E461900E75388 /* KLCircleViewController */,
773DA3FC179E461900E75388 /* KLCircleViewControllerTests */,
773DA3E4179E461900E75388 /* Frameworks */,
773DA3E3179E461900E75388 /* Products */,
);
sourceTree = "<group>";
};
773DA3E3179E461900E75388 /* Products */ = {
isa = PBXGroup;
children = (
773DA3E2179E461900E75388 /* libKLCircleViewController.a */,
773DA3F3179E461900E75388 /* KLCircleViewControllerTests.octest */,
);
name = Products;
sourceTree = "<group>";
};
773DA3E4179E461900E75388 /* Frameworks */ = {
isa = PBXGroup;
children = (
778057C117B1CAE600D0BBDB /* UIKit.framework */,
773DA3E5179E461900E75388 /* Foundation.framework */,
773DA3F4179E461900E75388 /* SenTestingKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
773DA3E7179E461900E75388 /* KLCircleViewController */ = {
isa = PBXGroup;
children = (
773DA3EA179E461900E75388 /* KLCircleViewController.h */,
773DA3EC179E461900E75388 /* KLCircleViewController.m */,
773DA3E8179E461900E75388 /* Supporting Files */,
);
path = KLCircleViewController;
sourceTree = "<group>";
};
773DA3E8179E461900E75388 /* Supporting Files */ = {
isa = PBXGroup;
children = (
773DA3E9179E461900E75388 /* KLCircleViewController-Prefix.pch */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
773DA3FC179E461900E75388 /* KLCircleViewControllerTests */ = {
isa = PBXGroup;
children = (
773DA402179E461900E75388 /* KLCircleViewControllerTests.h */,
773DA403179E461900E75388 /* KLCircleViewControllerTests.m */,
773DA3FD179E461900E75388 /* Supporting Files */,
);
path = KLCircleViewControllerTests;
sourceTree = "<group>";
};
773DA3FD179E461900E75388 /* Supporting Files */ = {
isa = PBXGroup;
children = (
773DA3FE179E461900E75388 /* KLCircleViewControllerTests-Info.plist */,
773DA3FF179E461900E75388 /* InfoPlist.strings */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
773DA3E1179E461900E75388 /* KLCircleViewController */ = {
isa = PBXNativeTarget;
buildConfigurationList = 773DA407179E461900E75388 /* Build configuration list for PBXNativeTarget "KLCircleViewController" */;
buildPhases = (
773DA3DE179E461900E75388 /* Sources */,
773DA3DF179E461900E75388 /* Frameworks */,
773DA3E0179E461900E75388 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = KLCircleViewController;
productName = KLCircleViewController;
productReference = 773DA3E2179E461900E75388 /* libKLCircleViewController.a */;
productType = "com.apple.product-type.library.static";
};
773DA3F2179E461900E75388 /* KLCircleViewControllerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 773DA40A179E461900E75388 /* Build configuration list for PBXNativeTarget "KLCircleViewControllerTests" */;
buildPhases = (
773DA3EE179E461900E75388 /* Sources */,
773DA3EF179E461900E75388 /* Frameworks */,
773DA3F0179E461900E75388 /* Resources */,
773DA3F1179E461900E75388 /* ShellScript */,
);
buildRules = (
);
dependencies = (
773DA3FA179E461900E75388 /* PBXTargetDependency */,
);
name = KLCircleViewControllerTests;
productName = KLCircleViewControllerTests;
productReference = 773DA3F3179E461900E75388 /* KLCircleViewControllerTests.octest */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
773DA3DA179E461900E75388 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0460;
ORGANIZATIONNAME = "Kieran Lafferty";
};
buildConfigurationList = 773DA3DD179E461900E75388 /* Build configuration list for PBXProject "KLCircleViewController" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 773DA3D9179E461900E75388;
productRefGroup = 773DA3E3179E461900E75388 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
773DA3E1179E461900E75388 /* KLCircleViewController */,
773DA3F2179E461900E75388 /* KLCircleViewControllerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
773DA3F0179E461900E75388 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
773DA401179E461900E75388 /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
773DA3F1179E461900E75388 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
773DA3DE179E461900E75388 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
773DA3ED179E461900E75388 /* KLCircleViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
773DA3EE179E461900E75388 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
773DA404179E461900E75388 /* KLCircleViewControllerTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
773DA3FA179E461900E75388 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 773DA3E1179E461900E75388 /* KLCircleViewController */;
targetProxy = 773DA3F9179E461900E75388 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
773DA3FF179E461900E75388 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
773DA400179E461900E75388 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
773DA405179E461900E75388 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
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_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
773DA406179E461900E75388 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
773DA408179E461900E75388 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
DSTROOT = /tmp/KLCircleViewController.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "KLCircleViewController/KLCircleViewController-Prefix.pch";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
773DA409179E461900E75388 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
DSTROOT = /tmp/KLCircleViewController.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "KLCircleViewController/KLCircleViewController-Prefix.pch";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
773DA40B179E461900E75388 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"\"$(SDKROOT)/Developer/Library/Frameworks\"",
"\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
);
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "KLCircleViewController/KLCircleViewController-Prefix.pch";
INFOPLIST_FILE = "KLCircleViewControllerTests/KLCircleViewControllerTests-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = octest;
};
name = Debug;
};
773DA40C179E461900E75388 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"\"$(SDKROOT)/Developer/Library/Frameworks\"",
"\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
);
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "KLCircleViewController/KLCircleViewController-Prefix.pch";
INFOPLIST_FILE = "KLCircleViewControllerTests/KLCircleViewControllerTests-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = octest;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
773DA3DD179E461900E75388 /* Build configuration list for PBXProject "KLCircleViewController" */ = {
isa = XCConfigurationList;
buildConfigurations = (
773DA405179E461900E75388 /* Debug */,
773DA406179E461900E75388 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
773DA407179E461900E75388 /* Build configuration list for PBXNativeTarget "KLCircleViewController" */ = {
isa = XCConfigurationList;
buildConfigurations = (
773DA408179E461900E75388 /* Debug */,
773DA409179E461900E75388 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
773DA40A179E461900E75388 /* Build configuration list for PBXNativeTarget "KLCircleViewControllerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
773DA40B179E461900E75388 /* Debug */,
773DA40C179E461900E75388 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 773DA3DA179E461900E75388 /* Project object */;
}

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "773DA3E1179E461900E75388"
BuildableName = "libKLCircleViewController.a"
BlueprintName = "KLCircleViewController"
ReferencedContainer = "container:KLCircleViewController.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "773DA3F2179E461900E75388"
BuildableName = "KLCircleViewControllerTests.octest"
BlueprintName = "KLCircleViewControllerTests"
ReferencedContainer = "container:KLCircleViewController.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>KLCircleViewController.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>773DA3E1179E461900E75388</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>773DA3F2179E461900E75388</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "773DA3E1179E461900E75388"
BuildableName = "libKLCircleViewController.a"
BlueprintName = "KLCircleViewController"
ReferencedContainer = "container:KLCircleViewController.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "773DA3F2179E461900E75388"
BuildableName = "KLCircleViewControllerTests.octest"
BlueprintName = "KLCircleViewControllerTests"
ReferencedContainer = "container:KLCircleViewController.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>KLCircleViewController.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>773DA3E1179E461900E75388</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>773DA3F2179E461900E75388</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'KLCircleViewController' target in the 'KLCircleViewController' project
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif

View File

@@ -0,0 +1,245 @@
//
// KLCircleViewController.h
// KLCircleViewController
//
// Created by Kieran Lafferty on 2013-07-23.
// Copyright (c) 2013 Kieran Lafferty. All rights reserved.
//
#import <UIKit/UIKit.h>
@class KLCircleViewController, KLContainerViewController;
typedef enum
{
KLCircleStateCenter = 1,
KLCircleStateLeft = 2,
KLCircleStateRight = 3,
KLCircleStateTop = 4, //Currently not used
KLCircleStateBottom = 5
} KLCircleState;
typedef enum {
KLToggleDirectionNone,
KLToggleDirectionUp,
KLToggleDirectionDown,
KLToggleDirectionLeft,
KLToggleDirectionRight,
} KLToggleDirection;
/**
* Block type for handling state transitions
*
* @param circleViewController Reference to the controller undergoing the state change
* @param fromState State of the controller before the state change has occured
* @param toState State of the controller after the state change has occured
*/
typedef void (^stateChangeHandler) (KLCircleViewController* circleViewController,
KLCircleState fromState,
KLCircleState toState);
@interface KLCircleViewController : UIViewController
#pragma mark - Initializers
/**
* Static initializer creates an instance of KLCircleViewController with a center view controller only
*
* @param centerViewController The initial view controller that is at the center position
*
* @return KLCircleViewController reference to the newly initialized view controller
*/
+(id) circleViewControllerWithCenterViewController: (UIViewController*) centerViewController;
/**
* Static initializer creates an instance of KLCircleViewController with a center, left, right, bottom view controllers
*
* @param centerViewController The initial view controller that is at the center position
* @param leftViewController The initial view controller that is at the left position
* @param rightViewController The initial view controller that is at the right position
* @param bottomViewController The initial view controller that is at the bottom position
*
* @return KLCircleViewController reference to the newly initialized view controller
*/
+(id) circleViewControllerWithCenterViewController: (UIViewController*) centerViewController
leftViewController: (UIViewController*) leftViewController
rightViewController: (UIViewController*) rightViewController
bottomViewController: (UIViewController*) bottomViewController;
/**
* Initializer creates an instance of KLCircleViewController with a center view controller only
*
* @param centerViewController The initial view controller that is at the center position
*
* @return KLCircleViewController reference to the newly initialized view controller
*/
-(id) initWithCenterViewController: (UIViewController*) centerViewController;
/**
* Initializer creates an instance of KLCircleViewController with a center, left, right, bottom view controllers
*
* @param centerViewController The initial view controller that is at the center position
* @param leftViewController The initial view controller that is at the left position
* @param rightViewController The initial view controller that is at the right position
* @param bottomViewController The initial view controller that is at the bottom position
*
* @return KLCircleViewController reference to the newly initialized view controller
*/
-(id) initWithCenterViewController: (UIViewController*) centerViewController
leftViewController: (UIViewController*) leftViewController
rightViewController: (UIViewController*) rightViewController
bottomViewController: (UIViewController*) bottomViewController;
#pragma mark - State modifiers
/**
* Programatically trigger a state transition. State transitions can will only occur as per the rules defined in shouldTransitionToState method in the class extension in implementation file
*
* @param state State to transition to
* @param animated Set YES if you want the transition to be animated, NO otherwise
*/
-(void) setState: (KLCircleState) state
animated: (BOOL) animated;
/**
* Programatically trigger a state transition. State transitions can will only occur as per the rules defined in shouldTransitionToState method in the class extension in implementation file
*
* @param state State to transition to
* @param animated Set YES if you want the transition to be animated, NO otherwise
* @param duration Duration of the animation
* @param completion Completion block which is fired at the end of the animation
*/
-(void) setState: (KLCircleState) state
animated: (BOOL) animated
duration: (NSTimeInterval) duration
completion: (stateChangeHandler) completion;
/**
* Returns the current state of the control
*
* @return KLCircleState enum that corresponds to the current state of the control
*/
-(KLCircleState) state;
#pragma mark - Convenience methods
/**
* Convenience method that returns the view controller for the provided state or nil if does not exist
*
* @param state State to query for the associated view controller
*
* @return UIViewController The view controller for the provided state
*/
-(UIViewController*) viewControllerForState:(KLCircleState) state;
#pragma mark - Configuration
/**
* The main view controller that serves as the root
*/
@property(nonatomic, strong) IBOutlet UIViewController* centerViewController;
/**
* The view controller that is exposed by panning to the left from the center
*/
@property(nonatomic, strong) UIViewController* leftViewController;
/**
* The view controller that is exposed by panning to the right from the center
*/
@property(nonatomic, strong) UIViewController* rightViewController;
/**
* The view controller that is exposed by panning down from the center
*/
@property(nonatomic, strong) UIViewController* bottomViewController;
#pragma mark - Block Handlers
/**
* Block called immediately before a state transition occurs
*/
@property(nonatomic, copy) stateChangeHandler willTransitionState;
/**
* Block called immediately after a state transition occurs
*/
@property(nonatomic, copy) stateChangeHandler didTransitionState;
#pragma mark - Behavioural Configuration Parameters
/**
* Represents the size of the ledge shown while in KLCircleStateLeft
*/
@property(nonatomic, assign) CGFloat leftLedgeSize;
/**
* Minimum distance to pan in pixel points using UIPanGestureRecognizer before control will enter KLCircleStateLeft
*/
@property(nonatomic, assign) CGFloat leftMinToggleDistance;
/**
* Represents the size of the ledge shown while in KLCircleStateRight
*/
@property(nonatomic, assign) CGFloat rightLedgeSize;
/**
* Minimum distance to pan in pixel points using UIPanGestureRecognizer before control will enter KLCircleStateRight
*/
@property(nonatomic, assign) CGFloat rightMinToggleDistance;
/**
* Represents the size of the ledge shown while in KLCircleStateBottom
*/
@property(nonatomic, assign) CGFloat bottomLedgeSize;
/**
* Minimum distance to pan in pixel points using UIPanGestureRecognizer before control will enter KLCircleStateBottom
*/
@property(nonatomic, assign) CGFloat bottomMinToggleDistance;
/**
* Minimum distance to pan using UIPanGestureRecognizer before control will enter KLCircleStateCenter
*/
@property(nonatomic, assign) CGFloat centerMinToggleDistance;
@end
typedef enum {
KLDirectionPanGestureRecognizerVertical = 1,
KLDirectionPanGestureRecognizerHorizontal = 2
} KLDirectionPanGestureRecognizerDirection;
/**
* Custom Pan Gesture Recognizer that locks to either horizontal or vertical directions
*/
@interface KLDirectionPanGestureRecognizer : UIPanGestureRecognizer {
BOOL _drag;
int _moveX;
int _moveY;
KLDirectionPanGestureRecognizerDirection _direction;
}
@property (nonatomic, assign) KLDirectionPanGestureRecognizerDirection direction;
@end
/**
* Associated object that weakly references the circleController for the UIViewController
*/
@interface UIViewController (ContainerControllerItem)
@property(nonatomic, weak) KLCircleViewController *circleController;
@end
@interface KLContainerViewController : UIViewController
-(id) initWithViewController:(UIViewController*) viewController;
@property (nonatomic, strong) UIViewController* viewController;
@end

View File

@@ -0,0 +1,778 @@
//
// KLCircleViewController.m
// KLCircleViewController
//
// Created by Kieran Lafferty on 2013-07-23.
// Copyright (c) 2013 Kieran Lafferty. All rights reserved.
//
#import "KLCircleViewController.h"
#import <UIKit/UIGestureRecognizerSubclass.h>
#import <objc/runtime.h>
#define kDefaultAnimationDuration 0.3
#define kCenterSideLedgeSize 60
#define kDefaultSideOffset CGSizeMake(0,10)
#define kDefaultBottomOffset CGSizeMake(10, 0)
#define kStateMovementThreshold 50.0 //Must move this much to toggle next state
@interface KLCircleViewController()
@property (nonatomic, assign) CGRect panGestureStartFrame;
/**
* Container view is used to manage panning between the view controllers
*/
@property (nonatomic, strong) UIScrollView* containerView;
/**
* The gesture recognizer responsible for initializing state transitions via sliding
*/
@property (nonatomic, strong) KLDirectionPanGestureRecognizer* panGesture;
/**
* The gesture recognizer responsible for initializing state transitions via tapping
*/
@property (nonatomic, strong) UITapGestureRecognizer* tapGesture;
/**
* Maintains the current state of the controller.
*/
@property (nonatomic, assign) KLCircleState state;
/**
* Determines whether the transition should be allowed to occur. The state transition can only occur from the center to [top, left, bottom, right]. And from [top, left, bottom, right] to center. Will return false if the toState does not have an associated view controller.
*
* @param toState The state that the control is attempting to transition to.
* @param fromState The state that the control is attempting to transition from.
*
* @return BOOL if the transition can occur
*/
-(BOOL) shouldTransitionToState:(KLCircleState) toState fromState:(KLCircleState) fromState;
/**
* Returns true if a view controller exists for the state and false if it does not
*
* @param state The state to be checked against
*
* @return boolean if a view controller exists
*/
-(BOOL) viewControllerExistsForState:(KLCircleState) state;
/**
* Called immediately before a state transition occurs
*
* @param state The state being transitioned to
*/
-(void) notifyWillTransitionToState:(KLCircleState) toState fromState:(KLCircleState) fromState;
/**
* Called immediately after a state transition occurs
*
* @param state The state being transitioned to
*/
-(void) notifyDidTransitionToState:(KLCircleState) toState fromState:(KLCircleState) fromState;
/**
* Returns the coordinate for the origin of the view controller view for the specified state. WARNING: Depends on the centerViewController view frame, so the center state must be set for this to be reliable.
*
* @param state the state for which to provide the origin for
*
* @return CGPoint point that contains the location data for state
*/
-(CGPoint) originForState:(KLCircleState) state;
/**
* Handles the animation for the pan gesture on the horizontal axis
*
* @param gesture Gesture to be handled
*/
-(void) handleHorizontalGesture:(UIPanGestureRecognizer*) gesture;
/**
* Handles the animation for the pan gesture on the vertical axis
*
* @param gesture Gesture to be handled
*/
-(void) handleVerticalGesture:(UIPanGestureRecognizer*) gesture;
/**
* Determines the appropriate content size of the UIScrollView and lays out the views in the correct locations
*/
-(void) layoutSubviewsOfContainer;
/**
* Sets up all the default values for the control. Should not be modified directly, if you would like to modify the defaults then set the properties directly from the instantiating class
*/
-(void) configureDefaults;
/**
* Performs common actions on the view controller removing it from the control
*
* @param viewController UIViewController to process
*/
-(void) removePeripheralViewController:(UIViewController*) viewController;
/**
* Performs common actions on the view controller adding it to the control
*
* @param viewController UIViewController to process
*/
-(void) addPeripheralViewController:(UIViewController*) viewController;
@end
@implementation KLCircleViewController
#pragma mark - Initializers
-(id) initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder: aDecoder]) {
[self commonInitialization];
}
return self;
}
- (void)commonInitialization
{
/**
* Layout of UIScrollView
*
* | | |
* |
*/
[self configureDefaults];
_containerView = [[UIScrollView alloc] initWithFrame: self.view.bounds];
[_containerView setBackgroundColor: [UIColor blackColor]];
[_containerView setScrollEnabled: NO];
//Initialize attributes of scroll view
[self.view addSubview: _containerView];
//Initialize the gesture recognizers
_panGesture = [[KLDirectionPanGestureRecognizer alloc] initWithTarget:self
action:@selector(didPerformPanGesture:)];
[_panGesture reset];
[_containerView addGestureRecognizer: _panGesture];
_tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(didPerformTapGesture:)];
}
/**
* Sets the local view controller property and adds it as a child view controller to the control
*
* @param centerViewController The initial view controller that is at the center position
* @param leftViewController The initial view controller that is at the left position
* @param rightViewController The initial view controller that is at the right position
* @param bottomViewController The initial view controller that is at the bottom position
*
* @return KLCircleViewController reference to the newly initialized view controller
*/
-(id) initWithCenterViewController: (UIViewController*) centerViewController
leftViewController: (UIViewController*) leftViewController
rightViewController: (UIViewController*) rightViewController
bottomViewController: (UIViewController*) bottomViewController {
if (self = [self init]) {
[self commonInitialization];
//Set the center view and add it to the scrollview
[self setCenterViewController: centerViewController];
//Add and configure the right view
[self setRightViewController: rightViewController];
//Add and configure the left view
[self setLeftViewController: leftViewController];
//Add and configure the bottom view
[self setBottomViewController: bottomViewController];
[self setState: KLCircleStateCenter];
}
return self;
}
/**
* Sets the local view controller property and adds it as a child view controller to the control
*
* @param centerViewController The initial view controller that is at the center position
* @param leftViewController The initial view controller that is at the left position
* @param rightViewController The initial view controller that is at the right position
* @param bottomViewController The initial view controller that is at the bottom position
*
* @return KLCircleViewController reference to the newly initialized view controller
*/
+(id) circleViewControllerWithCenterViewController: (UIViewController*) centerViewController
leftViewController: (UIViewController*) leftViewController
rightViewController: (UIViewController*) rightViewController
bottomViewController: (UIViewController*) bottomViewController {
return [[KLCircleViewController alloc] initWithCenterViewController: centerViewController
leftViewController: leftViewController
rightViewController: rightViewController
bottomViewController: bottomViewController];
}
/**
* Sets the local view controller property and adds it as a child view controller to the control
*
* @param centerViewController view controller to set as the center view controller
*
* @return reference to the newly intialized control
*/
-(id) initWithCenterViewController: (UIViewController*) centerViewController {
NSAssert(centerViewController, @"Must provide a center view controller");
if (self = [self initWithCenterViewController: centerViewController
leftViewController: nil
rightViewController: nil
bottomViewController: nil]) {
}
return self;
}
/**
* Sets the local view controller property and adds it as a child view controller to the control
*
* @param centerViewController view controller to set as the center view controller
*
* @return reference to the newly intialized control
*/
+(id) circleViewControllerWithCenterViewController: (UIViewController*) centerViewController {
return [[KLCircleViewController alloc] initWithCenterViewController: centerViewController];
}
-(void) configureDefaults {
//Ledges
self.leftLedgeSize = kCenterSideLedgeSize;
self.rightLedgeSize = kCenterSideLedgeSize;
self.bottomLedgeSize = kCenterSideLedgeSize;
//Toggle Distance
self.leftMinToggleDistance = kStateMovementThreshold;
self.rightMinToggleDistance = kStateMovementThreshold;
self.bottomMinToggleDistance = kStateMovementThreshold;
self.centerMinToggleDistance = kStateMovementThreshold;
}
#pragma mark - Setters
-(void) setCenterViewController:(UIViewController *)centerViewController {
if (_centerViewController) {
[self removePeripheralViewController: _centerViewController];
}
_centerViewController = centerViewController;
[_centerViewController setCircleController: self];
[_centerViewController.view addGestureRecognizer: _tapGesture];
[self addChildViewController: _centerViewController];
[_containerView addSubview: _centerViewController.view];
[self layoutSubviewsOfContainer];
}
-(void) setLeftViewController:(UIViewController *)leftViewController {
if (_leftViewController) {
[self removePeripheralViewController: _leftViewController];
}
_leftViewController = [[KLContainerViewController alloc] initWithViewController: leftViewController];
if (leftViewController) {
[self addPeripheralViewController: _leftViewController];
}
[self layoutSubviewsOfContainer];
}
-(void) setRightViewController:(UIViewController *)rightViewController {
if (_rightViewController) {
[self removePeripheralViewController: _rightViewController];
}
_rightViewController = [[KLContainerViewController alloc] initWithViewController: rightViewController];
if (rightViewController) {
[self addPeripheralViewController: _rightViewController];
}
[self layoutSubviewsOfContainer];
}
-(void) setBottomViewController:(UIViewController *)bottomViewController {
if (_bottomViewController) {
[self removePeripheralViewController: _bottomViewController];
}
_bottomViewController = [[KLContainerViewController alloc] initWithViewController: bottomViewController];
if (bottomViewController) {
[self addPeripheralViewController:_bottomViewController];
}
[self layoutSubviewsOfContainer];
}
-(BOOL) shouldAutomaticallyForwardAppearanceMethods {
return YES;
}
#pragma mark - Helpers
-(void) removePeripheralViewController:(UIViewController*) viewController {
[viewController willMoveToParentViewController:nil];
[viewController setCircleController: nil];
[viewController removeFromParentViewController];
[viewController.view removeFromSuperview];
}
-(void) addPeripheralViewController:(UIViewController*) viewController {
[viewController setCircleController: self];
[self addChildViewController: viewController];
[_containerView insertSubview: viewController.view
belowSubview: self.centerViewController.view];
[viewController didMoveToParentViewController: self];
}
-(void) layoutSubviewsOfContainer {
//Add the content inset if necessary
[self.containerView setContentInset: UIEdgeInsetsMake(0, self.leftViewController ? self.leftLedgeSize : 0 , self.bottomViewController ? self.bottomLedgeSize : 0 , self.rightViewController ? self.rightLedgeSize : 0)];
[_centerViewController.view setFrame: [self frameForState: KLCircleStateCenter]];
[_leftViewController.view setFrame: [self frameForState: KLCircleStateLeft]];
[_rightViewController.view setFrame: [self frameForState: KLCircleStateRight]];
[_bottomViewController.view setFrame: [self frameForState: KLCircleStateBottom]];
//Set the containerviews content size to just fit the subviews
[self.containerView setContentSize: [self contentSizeToFit]];
[self setState: self.state];
}
-(CGSize) contentSizeToFit {
CGRect contentRect = CGRectZero;
for (UIView *view in self.containerView.subviews)
contentRect = CGRectUnion(contentRect, view.frame);
return contentRect.size;
}
-(CGSize) offsetTravelledByLastPan {
//Determine x offset
CGRect newFrame = [self.view convertRect: self.view.frame
toView: self.containerView];
//Create a CGsize by getting the difference between the saved frame and the new one. Negative values indicate backwards movement.
return CGSizeMake(newFrame.origin.x - self.panGestureStartFrame.origin.x, newFrame.origin.y - self.panGestureStartFrame.origin.y);
}
-(KLToggleDirection) nextStateDirection:(CGSize) movement {
//Determine if it was horizontal or vertical movement
BOOL isHorizontalMovement = abs(movement.width) > abs(movement.height);
if (isHorizontalMovement) {
//Horizontal movement
return movement.width >= 0 ? KLToggleDirectionRight : KLToggleDirectionLeft;
}
else {
//Vertical movement
return movement.height >= 0 ? KLToggleDirectionDown : KLToggleDirectionUp;
}
}
-(KLCircleState) stateFromDirection:(KLToggleDirection) direction {
KLCircleState nextState = self.state;
switch (self.state) {
case KLCircleStateCenter:
if (direction == KLToggleDirectionLeft)
nextState = KLCircleStateLeft;
else if (direction == KLToggleDirectionRight)
nextState = KLCircleStateRight;
else if (direction == KLToggleDirectionDown)
nextState = KLCircleStateBottom;
break;
case KLCircleStateLeft:
if (direction == KLToggleDirectionRight)
nextState = KLCircleStateCenter;
break;
case KLCircleStateRight:
if (direction == KLToggleDirectionLeft)
nextState = KLCircleStateCenter;
break;
case KLCircleStateBottom:
if (direction == KLToggleDirectionUp)
nextState = KLCircleStateCenter;
break;
default:
break;
}
return nextState;
}
-(KLCircleState) stateForCurrentView {
CGSize movementOffset = [self offsetTravelledByLastPan];
KLCircleState nextState = [self stateFromDirection: [self nextStateDirection:movementOffset]];
if (nextState == KLCircleStateLeft
&& abs(movementOffset.width) > self.leftMinToggleDistance) {
return KLCircleStateLeft;
}
else if (nextState == KLCircleStateRight
&& abs(movementOffset.width) > self.rightMinToggleDistance) {
return KLCircleStateRight;
}
else if (nextState == KLCircleStateBottom
&& abs(movementOffset.height) > self.bottomMinToggleDistance) {
return KLCircleStateBottom;
}
else if (nextState == KLCircleStateCenter
&& (abs(movementOffset.width) > self.centerMinToggleDistance
|| abs(movementOffset.height) > self.centerMinToggleDistance)) {
return KLCircleStateCenter;
}
else return self.state;
}
-(CGRect) frameForState: (KLCircleState) state {
CGPoint origin = [self originForState: state];
UIViewController* stateViewController = [self viewControllerForState: state];
return CGRectMake(origin.x, origin.y, stateViewController.view.frame.size.width, stateViewController.view.frame.size.height);
}
-(CGPoint) originForState:(KLCircleState) state {
CGPoint returnPoint = CGPointMake(0, 0);
CGRect centerFrame = self.centerViewController.view.frame;
if (state == KLCircleStateCenter) {
returnPoint.x = self.leftViewController ? self.leftViewController.view.frame.size.width - self.leftLedgeSize : 0;
}
else if (state == KLCircleStateLeft) {
//Do nothing, already at (0,0)
}
else if (state == KLCircleStateRight) {
returnPoint.x = self.leftViewController ? self.leftViewController.view.frame.size.width + self.centerViewController.view.frame.size.width - self.leftLedgeSize - self.rightLedgeSize : self.centerViewController.view.frame.size.width - self.rightLedgeSize;
}
else if (state == KLCircleStateBottom) {
returnPoint.x = centerFrame.origin.x;
returnPoint.y = centerFrame.origin.y + centerFrame.size.height - self.bottomLedgeSize;
}
return returnPoint;
}
-(BOOL) shouldTransitionToState:(KLCircleState) toState fromState:(KLCircleState) fromState {
if (fromState == toState) {
return YES;
}
//Can only transition if either the fromState or toState is the centerViewController. This prevents transitions from leaf view controllers to other leaf view controllers. Can also transition from the left to the right view and vice versa
return ((toState == KLCircleStateCenter || fromState == KLCircleStateCenter) ||
(toState == KLCircleStateLeft && fromState == KLCircleStateRight) ||
(toState == KLCircleStateRight && fromState == KLCircleStateLeft)) &&
[self viewControllerExistsForState: toState];
}
-(BOOL) viewControllerExistsForState:(KLCircleState) state {
return [self viewControllerForState: state] != nil;
}
-(UIViewController*) viewControllerForState:(KLCircleState) state {
switch (state) {
case KLCircleStateCenter:
return self.centerViewController;
break;
case KLCircleStateLeft:
return self.leftViewController;
break;
case KLCircleStateRight:
return self.rightViewController;
break;
// case KLCircleStateTop:
// return self.topViewController;
// break;
case KLCircleStateBottom:
return self.bottomViewController;
break;
default:
break;
}
return nil;
}
#pragma mark - State transitions
/**
* Only publicly available method for triggering state changes progamatically.
*
* @param state state to be transitioned to
* @param animated boolean which indicates whether the transition should be animated or not
*/
-(void) setState:(KLCircleState)state
animated:(BOOL)animated {
[self setState: state
animated: animated
duration: kDefaultAnimationDuration
completion: nil];
}
-(void) setState: (KLCircleState) state
animated: (BOOL) animated
duration: (NSTimeInterval) duration
completion: (stateChangeHandler) completion {
__block KLCircleState lastState = self.state;
if (animated) {
[UIView animateWithDuration: duration
animations:^{
[self setState: state];
}
completion:^(BOOL finished) {
if (completion) {
completion(self, lastState, state);
}
}];
}
else {
[self setState: state];
if (completion) {
completion(self, lastState, state);
}
}
}
/**
* Private method to manage the state property and the final frame properties of the control to move to the specified state.
*
* @param state state to be transitioned to
*/
-(void) setState:(KLCircleState)state {
KLCircleState lastState = self.state;
if ([self shouldTransitionToState: state
fromState: lastState]) {
[self notifyWillTransitionToState: state fromState:lastState];
//TODO: Add animation logic here for final state drawing
CGPoint pointForState = [self originForState: state];
[self.containerView setContentOffset: pointForState];
_state = state;
[self notifyDidTransitionToState: state
fromState: lastState];
}
}
#pragma mark - Notifications
/**
* Sends out all notification mechanisms to indicate a transition will occur immediately following execution.
*
* @param toState current state of the control before the state change occurs
* @param fromState state to be transitioned to
*/
-(void) notifyWillTransitionToState:(KLCircleState) toState fromState:(KLCircleState) fromState {
//Notify the event handler(s)
if (self.willTransitionState)
self.willTransitionState(self, toState, fromState);
}
/**
* Sends out all notification mechanisms to indicate a transition did occur immediately preceding execution.
*
* @param toState current state of the control before the state change occured
* @param fromState state transitioned to
*/
-(void) notifyDidTransitionToState:(KLCircleState) toState fromState:(KLCircleState) fromState {
//Notify the event handler(s)
if (self.didTransitionState)
self.didTransitionState(self, toState, fromState);
}
#pragma mark - Gesture Recognizers
/**
* UITapGestureRecognizer handler.
*
* @param gesture UITapGestureRecognizer
*/
-(void) didPerformTapGesture:(UITapGestureRecognizer*) gesture {
//Determine if it is in a tap sensitive zone
//Toggle accordingly
if (self.state == KLCircleStateLeft || self.state == KLCircleStateRight || self.state == KLCircleStateBottom) {
if (gesture.view == self.centerViewController.view) {
[self setState: KLCircleStateCenter
animated: YES];
}
}
}
/**
* UISwipeGestureRecognizer handler. Only toggles the center state if the contained in the left/right view controller and the swipe direction is left/right.
*
* @param gesture UITapGestureRecognizer
*/
-(void) didPerformSwipeGesture:(UISwipeGestureRecognizer*) gesture {
//Swipe gestures are already configured to only recognize the correct direction for the left and right ones
[self setState: KLCircleStateCenter
animated: YES];
}
/**
* UIPanGestureRecognizer handler.
*
* @param gesture UIPanGestureRecognizer
*/
-(void) didPerformPanGesture:(KLDirectionPanGestureRecognizer*) gesture {
if (gesture.state == UIGestureRecognizerStateBegan) {
//TODO: Save the currently visible frame so taht we can figure out offset once completed
self.panGestureStartFrame = [self.view convertRect: self.view.frame
toView: self.containerView];
}
else if(gesture.state == UIGestureRecognizerStateChanged) {
if (gesture.direction == KLDirectionPanGestureRecognizerHorizontal) {
[self handleHorizontalGesture: gesture];
}
else if (gesture.direction == KLDirectionPanGestureRecognizerVertical){
[self handleVerticalGesture: gesture];
}
}
else if (gesture.state == UIGestureRecognizerStateEnded
|| gesture.state == UIGestureRecognizerStateCancelled
|| gesture.state == UIGestureRecognizerStateFailed) {
[gesture reset];
[self setState: [self stateForCurrentView]
animated: YES];
}
}
-(void) handleHorizontalGesture:(UIPanGestureRecognizer*) gesture {
//Ignore horizontal swipes if not in left center or right
if (!(self.state == KLCircleStateLeft || self.state == KLCircleStateCenter || self.state == KLCircleStateRight))
return;
CGPoint translation = [gesture translationInView: self.view];
CGPoint containerOffset = self.containerView.contentOffset;
containerOffset.x -= translation.x;
//Leftmost side
if (containerOffset.x < 0) {
if (self.leftViewController)
containerOffset = [self originForState: KLCircleStateLeft];
else
containerOffset = [self originForState: KLCircleStateCenter];
}
//Rightmost side
else if (fabsf(containerOffset.x + gesture.view.frame.size.width) > self.containerView.contentSize.width) {
if (self.rightViewController)
containerOffset = [self originForState: KLCircleStateRight];
else
containerOffset = [self originForState: KLCircleStateCenter];
}
[gesture setTranslation:CGPointZero inView: self.view];
[self.containerView setContentOffset: containerOffset];
}
-(void) handleVerticalGesture:(UIPanGestureRecognizer*) gesture {
if (!(self.state == KLCircleStateBottom || self.state == KLCircleStateCenter))
return;
//TODO: implementation
CGPoint translation = [gesture translationInView: self.view];
CGPoint containerOffset = self.containerView.contentOffset;
containerOffset.y -= translation.y;
//Leftmost side
if (containerOffset.y < 0) {
containerOffset = [self originForState: KLCircleStateCenter];
}
//Rightmost side
else if (fabsf(containerOffset.y + gesture.view.frame.size.height) > self.containerView.contentSize.height) {
containerOffset = [self originForState: KLCircleStateBottom];
}
[gesture setTranslation: CGPointZero
inView: self.view];
[self.containerView setContentOffset: containerOffset];
}
@end
int const static kDirectionPanThreshold = 5;
@implementation KLDirectionPanGestureRecognizer
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
if (self.state == UIGestureRecognizerStateFailed) return;
CGPoint nowPoint = [[touches anyObject] locationInView:self.view];
CGPoint prevPoint = [[touches anyObject] previousLocationInView:self.view];
_moveX += prevPoint.x - nowPoint.x;
_moveY += prevPoint.y - nowPoint.y;
if (!_drag) {
if (abs(_moveX) > abs(_moveY)) {
if (_direction == KLDirectionPanGestureRecognizerHorizontal) {
self.state = UIGestureRecognizerStateFailed;
}else {
_drag = YES;
self.direction = KLDirectionPanGestureRecognizerHorizontal;
}
}else if (abs(_moveY) > abs(_moveX)) {
if (_direction == KLDirectionPanGestureRecognizerVertical) {
self.state = UIGestureRecognizerStateFailed;
}else {
_drag = YES;
self.direction = KLDirectionPanGestureRecognizerVertical;
}
}
}
}
- (void)reset {
[super reset];
_drag = NO;
_direction = 0;
_moveX = 0;
_moveY = 0;
}
@end
@implementation UIViewController (ContainerControllerItem)
static const char* circleControllerKey = "CircleController";
-(void) setCircleController:(KLCircleViewController *)containerController {
objc_setAssociatedObject(self, &circleControllerKey, containerController, OBJC_ASSOCIATION_ASSIGN);
}
-(KLCircleViewController*) circleController {
return objc_getAssociatedObject(self, &circleControllerKey);
}
@end
@implementation KLContainerViewController
-(id) initWithViewController:(UIViewController*) viewController {
if (self = [super init]) {
[self setViewController: viewController];
}
return self;
}
-(void) setViewController:(UIViewController *)viewController {
if (_viewController) {
[_viewController removeFromParentViewController];
[_viewController.view removeFromSuperview];
}
_viewController = viewController;
if (viewController) {
[self addChildViewController: _viewController];
[self.view addSubview: _viewController.view];
}
}
-(void) setCircleController:(KLCircleViewController *)circleController {
[self.viewController setCircleController: circleController];
}
@end

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>KL.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@@ -0,0 +1,13 @@
//
// KLCircleViewControllerTests.h
// KLCircleViewControllerTests
//
// Created by Kieran Lafferty on 2013-07-23.
// Copyright (c) 2013 Kieran Lafferty. All rights reserved.
//
#import <SenTestingKit/SenTestingKit.h>
@interface KLCircleViewControllerTests : SenTestCase
@end

View File

@@ -0,0 +1,32 @@
//
// KLCircleViewControllerTests.m
// KLCircleViewControllerTests
//
// Created by Kieran Lafferty on 2013-07-23.
// Copyright (c) 2013 Kieran Lafferty. All rights reserved.
//
#import "KLCircleViewControllerTests.h"
@implementation KLCircleViewControllerTests
- (void)setUp
{
[super setUp];
// Set-up code here.
}
- (void)tearDown
{
// Tear-down code here.
[super tearDown];
}
- (void)testExample
{
STFail(@"Unit tests are not implemented yet in KLCircleViewControllerTests");
}
@end

View File

@@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */