diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c29c702 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control +# +Pods/ + +### +._* + +.hgignore diff --git a/Demo/LGPlusButtonsViewDemo.xcodeproj/project.pbxproj b/Demo/LGPlusButtonsViewDemo.xcodeproj/project.pbxproj new file mode 100644 index 0000000..defa14d --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo.xcodeproj/project.pbxproj @@ -0,0 +1,386 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1946D2D8D0CE8124E0632DEA /* libPods-LGPlusButtonsViewDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 23A4E5C49FE8BEAB57D05B49 /* libPods-LGPlusButtonsViewDemo.a */; }; + 4A3F4B5A1AA8BA51006D9DAA /* PlusViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A3F4B591AA8BA51006D9DAA /* PlusViewController.m */; }; + 847A899A1A9F298B004A8413 /* NavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 847A89971A9F298B004A8413 /* NavigationController.m */; }; + 847A899B1A9F298B004A8413 /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 847A89991A9F298B004A8413 /* TableViewController.m */; }; + 847A899E1A9F2C32004A8413 /* PlusScrollViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 847A899D1A9F2C32004A8413 /* PlusScrollViewController.m */; }; + 84C5B7CD1A9F22C800EEEB24 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 84C5B7CC1A9F22C800EEEB24 /* main.m */; }; + 84C5B7D01A9F22C800EEEB24 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 84C5B7CF1A9F22C800EEEB24 /* AppDelegate.m */; }; + 84C5B7D81A9F22C800EEEB24 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84C5B7D71A9F22C800EEEB24 /* Images.xcassets */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 23A4E5C49FE8BEAB57D05B49 /* libPods-LGPlusButtonsViewDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LGPlusButtonsViewDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4A3F4B581AA8BA51006D9DAA /* PlusViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlusViewController.h; sourceTree = ""; }; + 4A3F4B591AA8BA51006D9DAA /* PlusViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlusViewController.m; sourceTree = ""; }; + 6CA3D88515E7F3B71D89BE22 /* Pods-LGPlusButtonsViewDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LGPlusButtonsViewDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-LGPlusButtonsViewDemo/Pods-LGPlusButtonsViewDemo.release.xcconfig"; sourceTree = ""; }; + 847A89961A9F298B004A8413 /* NavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationController.h; sourceTree = ""; }; + 847A89971A9F298B004A8413 /* NavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NavigationController.m; sourceTree = ""; }; + 847A89981A9F298B004A8413 /* TableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewController.h; sourceTree = ""; }; + 847A89991A9F298B004A8413 /* TableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewController.m; sourceTree = ""; }; + 847A899C1A9F2C32004A8413 /* PlusScrollViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlusScrollViewController.h; sourceTree = ""; }; + 847A899D1A9F2C32004A8413 /* PlusScrollViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlusScrollViewController.m; sourceTree = ""; }; + 84C5B7C71A9F22C800EEEB24 /* LGPlusButtonsViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LGPlusButtonsViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 84C5B7CB1A9F22C800EEEB24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 84C5B7CC1A9F22C800EEEB24 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 84C5B7CE1A9F22C800EEEB24 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 84C5B7CF1A9F22C800EEEB24 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 84C5B7D71A9F22C800EEEB24 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + FF64EDB1BA04182CD80346D1 /* Pods-LGPlusButtonsViewDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LGPlusButtonsViewDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LGPlusButtonsViewDemo/Pods-LGPlusButtonsViewDemo.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 84C5B7C41A9F22C800EEEB24 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1946D2D8D0CE8124E0632DEA /* libPods-LGPlusButtonsViewDemo.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4A3F4B5C1AA8BDAD006D9DAA /* Demo View Controllers */ = { + isa = PBXGroup; + children = ( + 4A3F4B5D1AA8BDBA006D9DAA /* UIView */, + 4A3F4B5E1AA8BDBE006D9DAA /* UIScrollView */, + ); + name = "Demo View Controllers"; + sourceTree = ""; + }; + 4A3F4B5D1AA8BDBA006D9DAA /* UIView */ = { + isa = PBXGroup; + children = ( + 4A3F4B581AA8BA51006D9DAA /* PlusViewController.h */, + 4A3F4B591AA8BA51006D9DAA /* PlusViewController.m */, + ); + name = UIView; + sourceTree = ""; + }; + 4A3F4B5E1AA8BDBE006D9DAA /* UIScrollView */ = { + isa = PBXGroup; + children = ( + 847A899C1A9F2C32004A8413 /* PlusScrollViewController.h */, + 847A899D1A9F2C32004A8413 /* PlusScrollViewController.m */, + ); + name = UIScrollView; + sourceTree = ""; + }; + 6DC0BC0EF35C3CCDCDDDD0F1 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 23A4E5C49FE8BEAB57D05B49 /* libPods-LGPlusButtonsViewDemo.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 83663343D58C23F2EE00B73C /* Pods */ = { + isa = PBXGroup; + children = ( + FF64EDB1BA04182CD80346D1 /* Pods-LGPlusButtonsViewDemo.debug.xcconfig */, + 6CA3D88515E7F3B71D89BE22 /* Pods-LGPlusButtonsViewDemo.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 84C5B7BE1A9F22C800EEEB24 = { + isa = PBXGroup; + children = ( + 84C5B7C91A9F22C800EEEB24 /* LGPlusButtonsViewDemo */, + 84C5B7C81A9F22C800EEEB24 /* Products */, + 83663343D58C23F2EE00B73C /* Pods */, + 6DC0BC0EF35C3CCDCDDDD0F1 /* Frameworks */, + ); + sourceTree = ""; + }; + 84C5B7C81A9F22C800EEEB24 /* Products */ = { + isa = PBXGroup; + children = ( + 84C5B7C71A9F22C800EEEB24 /* LGPlusButtonsViewDemo.app */, + ); + name = Products; + sourceTree = ""; + }; + 84C5B7C91A9F22C800EEEB24 /* LGPlusButtonsViewDemo */ = { + isa = PBXGroup; + children = ( + 84C5B7CE1A9F22C800EEEB24 /* AppDelegate.h */, + 84C5B7CF1A9F22C800EEEB24 /* AppDelegate.m */, + 847A89961A9F298B004A8413 /* NavigationController.h */, + 847A89971A9F298B004A8413 /* NavigationController.m */, + 847A89981A9F298B004A8413 /* TableViewController.h */, + 847A89991A9F298B004A8413 /* TableViewController.m */, + 4A3F4B5C1AA8BDAD006D9DAA /* Demo View Controllers */, + 84C5B7D71A9F22C800EEEB24 /* Images.xcassets */, + 84C5B7CA1A9F22C800EEEB24 /* Supporting Files */, + ); + path = LGPlusButtonsViewDemo; + sourceTree = ""; + }; + 84C5B7CA1A9F22C800EEEB24 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 84C5B7CB1A9F22C800EEEB24 /* Info.plist */, + 84C5B7CC1A9F22C800EEEB24 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 84C5B7C61A9F22C800EEEB24 /* LGPlusButtonsViewDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 84C5B7EA1A9F22C800EEEB24 /* Build configuration list for PBXNativeTarget "LGPlusButtonsViewDemo" */; + buildPhases = ( + B1C231C3EE6FF3450126BB97 /* Check Pods Manifest.lock */, + 84C5B7C31A9F22C800EEEB24 /* Sources */, + 84C5B7C41A9F22C800EEEB24 /* Frameworks */, + 84C5B7C51A9F22C800EEEB24 /* Resources */, + 92F9790D16709FEEE544F8D3 /* Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LGPlusButtonsViewDemo; + productName = LGPlusButtonsViewDemo; + productReference = 84C5B7C71A9F22C800EEEB24 /* LGPlusButtonsViewDemo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 84C5B7BF1A9F22C800EEEB24 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = "Grigory Lutkov"; + TargetAttributes = { + 84C5B7C61A9F22C800EEEB24 = { + CreatedOnToolsVersion = 6.1.1; + }; + }; + }; + buildConfigurationList = 84C5B7C21A9F22C800EEEB24 /* Build configuration list for PBXProject "LGPlusButtonsViewDemo" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 84C5B7BE1A9F22C800EEEB24; + productRefGroup = 84C5B7C81A9F22C800EEEB24 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 84C5B7C61A9F22C800EEEB24 /* LGPlusButtonsViewDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 84C5B7C51A9F22C800EEEB24 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 84C5B7D81A9F22C800EEEB24 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 92F9790D16709FEEE544F8D3 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LGPlusButtonsViewDemo/Pods-LGPlusButtonsViewDemo-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + B1C231C3EE6FF3450126BB97 /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 84C5B7C31A9F22C800EEEB24 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4A3F4B5A1AA8BA51006D9DAA /* PlusViewController.m in Sources */, + 847A899E1A9F2C32004A8413 /* PlusScrollViewController.m in Sources */, + 847A899A1A9F298B004A8413 /* NavigationController.m in Sources */, + 84C5B7D01A9F22C800EEEB24 /* AppDelegate.m in Sources */, + 847A899B1A9F298B004A8413 /* TableViewController.m in Sources */, + 84C5B7CD1A9F22C800EEEB24 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 84C5B7E81A9F22C800EEEB24 /* 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; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + 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 = 6.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 84C5B7E91A9F22C800EEEB24 /* 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; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + 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 = 6.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 84C5B7EB1A9F22C800EEEB24 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FF64EDB1BA04182CD80346D1 /* Pods-LGPlusButtonsViewDemo.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Developer"; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = LGPlusButtonsViewDemo/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 84C5B7EC1A9F22C800EEEB24 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6CA3D88515E7F3B71D89BE22 /* Pods-LGPlusButtonsViewDemo.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Developer"; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = LGPlusButtonsViewDemo/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 84C5B7C21A9F22C800EEEB24 /* Build configuration list for PBXProject "LGPlusButtonsViewDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 84C5B7E81A9F22C800EEEB24 /* Debug */, + 84C5B7E91A9F22C800EEEB24 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 84C5B7EA1A9F22C800EEEB24 /* Build configuration list for PBXNativeTarget "LGPlusButtonsViewDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 84C5B7EB1A9F22C800EEEB24 /* Debug */, + 84C5B7EC1A9F22C800EEEB24 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 84C5B7BF1A9F22C800EEEB24 /* Project object */; +} diff --git a/Demo/LGPlusButtonsViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Demo/LGPlusButtonsViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..d1e10e7 --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Demo/LGPlusButtonsViewDemo.xcworkspace/contents.xcworkspacedata b/Demo/LGPlusButtonsViewDemo.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..fa3bd42 --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Demo/LGPlusButtonsViewDemo/AppDelegate.h b/Demo/LGPlusButtonsViewDemo/AppDelegate.h new file mode 100644 index 0000000..e87c1fb --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/AppDelegate.h @@ -0,0 +1,17 @@ +// +// AppDelegate.h +// LGPlusButtonsViewDemo +// +// Created by Grigory Lutkov on 26.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import +#import "NavigationController.h" + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; +@property (strong, nonatomic) UINavigationController *navigationController; + +@end diff --git a/Demo/LGPlusButtonsViewDemo/AppDelegate.m b/Demo/LGPlusButtonsViewDemo/AppDelegate.m new file mode 100644 index 0000000..173eef7 --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/AppDelegate.m @@ -0,0 +1,52 @@ +// +// AppDelegate.m +// LGPlusButtonsViewDemo +// +// Created by Grigory Lutkov on 26.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import "AppDelegate.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.navigationController = [NavigationController new]; + + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.rootViewController = self.navigationController; + self.window.backgroundColor = [UIColor whiteColor]; + [self.window makeKeyAndVisible]; + + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json b/Demo/LGPlusButtonsViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..c5fda8e --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,9 @@ +{ + "images" : [ + + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Contents.json b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..9da5e8e --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,134 @@ +{ + "images" : [ + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "Launch-Phone-55-P@3x.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "Launch-Phone-55-L@3x.png", + "minimum-system-version" : "8.0", + "orientation" : "landscape", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "667h", + "filename" : "Launch-Phone-47-P@2x.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Launch-Phone-35-P@2x.png", + "scale" : "2x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "retina4", + "filename" : "Launch-Phone-40-P@2x.png", + "minimum-system-version" : "7.0", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Launch-Pad-P@1x.png", + "scale" : "1x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Launch-Pad-L@1x.png", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Launch-Pad-P@2x.png", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "Launch-Pad-L@2x.png", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "filename" : "Launch-Phone-35-P@1x.png", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "filename" : "Launch-Phone-35-P@2x.png", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "filename" : "Launch-Phone-40-P@2x.png", + "subtype" : "retina4", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Launch-Pad-P@1x.png", + "scale" : "1x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Launch-Pad-L@1x.png", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Launch-Pad-P@2x.png", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "filename" : "Launch-Pad-L@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@1x.png b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@1x.png new file mode 100644 index 0000000..67c9e1d Binary files /dev/null and b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@1x.png differ diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@2x.png b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@2x.png new file mode 100644 index 0000000..2ce1e95 Binary files /dev/null and b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@2x.png differ diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@1x.png b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@1x.png new file mode 100644 index 0000000..369ade2 Binary files /dev/null and b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@1x.png differ diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@2x.png b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@2x.png new file mode 100644 index 0000000..d379a54 Binary files /dev/null and b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@2x.png differ diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@1x.png b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@1x.png new file mode 100644 index 0000000..107999c Binary files /dev/null and b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@1x.png differ diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@2x.png b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@2x.png new file mode 100644 index 0000000..b69f17f Binary files /dev/null and b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@2x.png differ diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-40-P@2x.png b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-40-P@2x.png new file mode 100644 index 0000000..6258ece Binary files /dev/null and b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-40-P@2x.png differ diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-47-P@2x.png b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-47-P@2x.png new file mode 100644 index 0000000..c257d16 Binary files /dev/null and b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-47-P@2x.png differ diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-L@3x.png b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-L@3x.png new file mode 100644 index 0000000..34ec1ed Binary files /dev/null and b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-L@3x.png differ diff --git a/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-P@3x.png b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-P@3x.png new file mode 100644 index 0000000..1b08e31 Binary files /dev/null and b/Demo/LGPlusButtonsViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-P@3x.png differ diff --git a/Demo/LGPlusButtonsViewDemo/Info.plist b/Demo/LGPlusButtonsViewDemo/Info.plist new file mode 100644 index 0000000..493646a --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.test.$(PRODUCT_NAME) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Demo/LGPlusButtonsViewDemo/NavigationController.h b/Demo/LGPlusButtonsViewDemo/NavigationController.h new file mode 100644 index 0000000..85ba524 --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/NavigationController.h @@ -0,0 +1,13 @@ +// +// NavigationController.h +// LGPlusButtonsViewDemo +// +// Created by Grigory Lutkov on 26.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import + +@interface NavigationController : UINavigationController + +@end diff --git a/Demo/LGPlusButtonsViewDemo/NavigationController.m b/Demo/LGPlusButtonsViewDemo/NavigationController.m new file mode 100644 index 0000000..1fe1b20 --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/NavigationController.m @@ -0,0 +1,36 @@ +// +// NavigationController.m +// LGPlusButtonsViewDemo +// +// Created by Grigory Lutkov on 26.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import "NavigationController.h" +#import "TableViewController.h" + +@interface NavigationController () + +@property (strong, nonatomic) TableViewController *tableViewController; + +@end + +@implementation NavigationController + +- (id)init +{ + self = [super init]; + if (self) + { + self.tableViewController = [TableViewController new]; + [self setViewControllers:@[self.tableViewController]]; + } + return self; +} + +- (BOOL)shouldAutorotate +{ + return self.topViewController.shouldAutorotate; +} + +@end diff --git a/Demo/LGPlusButtonsViewDemo/PlusScrollViewController.h b/Demo/LGPlusButtonsViewDemo/PlusScrollViewController.h new file mode 100644 index 0000000..24b17e9 --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/PlusScrollViewController.h @@ -0,0 +1,15 @@ +// +// PlusScrollViewController.h +// LGPlusButtonsViewDemo +// +// Created by Grigory Lutkov on 26.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import + +@interface PlusScrollViewController : UIViewController + +- (id)initWithTitle:(NSString *)title; + +@end diff --git a/Demo/LGPlusButtonsViewDemo/PlusScrollViewController.m b/Demo/LGPlusButtonsViewDemo/PlusScrollViewController.m new file mode 100644 index 0000000..1ab9b4e --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/PlusScrollViewController.m @@ -0,0 +1,135 @@ +// +// PlusScrollViewController.m +// LGPlusButtonsViewDemo +// +// Created by Grigory Lutkov on 26.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import "PlusScrollViewController.h" +#import "LGPlusButtonsView.h" +#import "LGDrawer.h" + +@interface PlusScrollViewController () + +@property (strong, nonatomic) UIScrollView *scrollView; +@property (strong, nonatomic) UILabel *textLabel; +@property (strong, nonatomic) LGPlusButtonsView *plusButtonsView; + +@end + +@implementation PlusScrollViewController + +- (id)initWithTitle:(NSString *)title +{ + self = [super init]; + if (self) + { + self.title = title; + + // ----- + + _scrollView = [UIScrollView new]; + _scrollView.backgroundColor = [UIColor whiteColor]; + _scrollView.alwaysBounceVertical = YES; + [self.view addSubview:_scrollView]; + + _textLabel = [UILabel new]; + _textLabel.backgroundColor = [UIColor clearColor]; + _textLabel.text = @"UIScrollView"; + [_scrollView addSubview:_textLabel]; + + _plusButtonsView = [[LGPlusButtonsView alloc] initWithView:_scrollView + numberOfButtons:3 + showsPlusButton:YES + actionHandler:^(LGPlusButtonsView *plusButtonView, NSString *title, NSString *description, NSUInteger index) + { + NSLog(@"%@, %@, %i", title, description, (int)index); + } + plusButtonActionHandler:nil]; + + [_plusButtonsView setButtonsTitles:@[@"+", @"1", @"2", @"3"] forState:UIControlStateNormal]; + [_plusButtonsView setDescriptionsTexts:@[@"", @"Button One description", @"Button Two description", @"Button Three description"]]; + _plusButtonsView.position = LGPlusButtonsViewPositionBottomRight; + _plusButtonsView.showWhenScrolling = YES; + _plusButtonsView.appearingAnimationType = LGPlusButtonsAppearingAnimationTypeCrossDissolveAndSlideVertical; + _plusButtonsView.buttonsAppearingAnimationType = LGPlusButtonsAppearingAnimationTypeCrossDissolveAndSlideHorizontal; + _plusButtonsView.plusButtonAnimationType = LGPlusButtonAnimationTypeRotate; + [_plusButtonsView setButtonsTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [_plusButtonsView setButtonsAdjustsImageWhenHighlighted:NO]; + + [_plusButtonsView showAnimated:NO completionHandler:nil]; + } + return self; +} + +#pragma mark - Dealloc + +- (void)dealloc +{ + NSLog(@"%s [Line %d]", __PRETTY_FUNCTION__, __LINE__); +} + +#pragma mark - Appearing + +- (void)viewWillLayoutSubviews +{ + [super viewWillLayoutSubviews]; + + _scrollView.frame = CGRectMake(0.f, 0.f, self.view.frame.size.width, self.view.frame.size.height); + + [_textLabel sizeToFit]; + _textLabel.center = CGPointMake(_scrollView.frame.size.width/2, 20.f+_textLabel.frame.size.height/2); + _textLabel.frame = CGRectIntegral(_textLabel.frame); + + _scrollView.contentSize = CGSizeMake(self.view.frame.size.width, 3000.f); + + // ----- + + BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation); + + CGFloat shadowBlur = 3.f; + CGFloat buttonSide = (isPortrait ? 64.f : 44.f); + CGFloat buttonsFontSize = (isPortrait ? 30.f : 20.f); + CGFloat plusButtonFontSize = buttonsFontSize*1.5; + + _plusButtonsView.contentInset = UIEdgeInsetsMake(shadowBlur, shadowBlur, shadowBlur, shadowBlur); + [_plusButtonsView setButtonsTitleFont:[UIFont boldSystemFontOfSize:buttonsFontSize]]; + + _plusButtonsView.plusButton.titleLabel.font = [UIFont systemFontOfSize:plusButtonFontSize]; + _plusButtonsView.plusButton.titleOffset = CGPointMake(0.f, -plusButtonFontSize*0.1); + + UIImage *circleImageNormal = [LGDrawer drawEllipseWithImageSize:CGSizeMake(buttonSide, buttonSide) + size:CGSizeMake(buttonSide-shadowBlur*2, buttonSide-shadowBlur*2) + offset:CGPointZero + rotate:0.f + backgroundColor:nil + fillColor:[UIColor colorWithRed:0.f green:0.5 blue:1.f alpha:1.f] + strokeColor:nil + strokeThickness:0.f + strokeDash:nil + strokeType:LGDrawerStrokeTypeInside + shadowColor:[UIColor colorWithWhite:0.f alpha:0.5] + shadowOffset:CGPointZero + shadowBlur:shadowBlur]; + + UIImage *circleImageHighlighted = [LGDrawer drawEllipseWithImageSize:CGSizeMake(buttonSide, buttonSide) + size:CGSizeMake(buttonSide-shadowBlur*2, buttonSide-shadowBlur*2) + offset:CGPointZero + rotate:0.f + backgroundColor:nil + fillColor:[UIColor colorWithRed:0.2 green:0.7 blue:1.f alpha:1.f] + strokeColor:nil + strokeThickness:0.f + strokeDash:nil + strokeType:LGDrawerStrokeTypeInside + shadowColor:[UIColor colorWithWhite:0.f alpha:0.5] + shadowOffset:CGPointZero + shadowBlur:shadowBlur]; + + [_plusButtonsView setButtonsImage:circleImageNormal forState:UIControlStateNormal]; + [_plusButtonsView setButtonsImage:circleImageHighlighted forState:UIControlStateHighlighted]; + [_plusButtonsView setButtonsImage:circleImageHighlighted forState:UIControlStateHighlighted|UIControlStateSelected]; +} + +@end diff --git a/Demo/LGPlusButtonsViewDemo/PlusViewController.h b/Demo/LGPlusButtonsViewDemo/PlusViewController.h new file mode 100644 index 0000000..39c074d --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/PlusViewController.h @@ -0,0 +1,15 @@ +// +// PlusViewController.h +// LGPlusButtonsViewDemo +// +// Created by Grigory Lutkov on 05.03.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import + +@interface PlusViewController : UIViewController + +- (id)initWithTitle:(NSString *)title; + +@end diff --git a/Demo/LGPlusButtonsViewDemo/PlusViewController.m b/Demo/LGPlusButtonsViewDemo/PlusViewController.m new file mode 100644 index 0000000..4fdd5ab --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/PlusViewController.m @@ -0,0 +1,120 @@ +// +// PlusViewController.m +// LGPlusButtonsViewDemo +// +// Created by Grigory Lutkov on 05.03.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import "PlusViewController.h" +#import "LGPlusButtonsView.h" + +@interface PlusViewController () + +@property (strong, nonatomic) UIView *contentView; +@property (strong, nonatomic) UILabel *textLabel; +@property (strong, nonatomic) LGPlusButtonsView *plusButtonsView; + +@end + +@implementation PlusViewController + +- (id)initWithTitle:(NSString *)title +{ + self = [super init]; + if (self) + { + self.title = title; + + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(showHideButtonsAction)]; + + // ----- + + _contentView = [UIView new]; + _contentView.backgroundColor = [UIColor whiteColor]; + [self.view addSubview:_contentView]; + + _textLabel = [UILabel new]; + _textLabel.backgroundColor = [UIColor clearColor]; + _textLabel.text = @"UIView"; + [_contentView addSubview:_textLabel]; + + _plusButtonsView = [[LGPlusButtonsView alloc] initWithView:_contentView + numberOfButtons:3 + showsPlusButton:NO + actionHandler:^(LGPlusButtonsView *plusButtonView, NSString *title, NSString *description, NSUInteger index) + { + NSLog(@"%@, %@, %i", title, description, (int)index); + } + plusButtonActionHandler:nil]; + + [_plusButtonsView setButtonsTitles:@[@"1", @"2", @"3"] forState:UIControlStateNormal]; + [_plusButtonsView setDescriptionsTexts:@[@"Button One description", @"Button Two description", @"Button Three description"]]; + _plusButtonsView.position = LGPlusButtonsViewPositionTopRight; + _plusButtonsView.showWhenScrolling = NO; + _plusButtonsView.appearingAnimationType = LGPlusButtonsAppearingAnimationTypeCrossDissolveAndPop; + [_plusButtonsView setButtonsTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [_plusButtonsView setButtonsAdjustsImageWhenHighlighted:NO]; + } + return self; +} + +- (void)showHideButtonsAction +{ + if (_plusButtonsView.isShowing) + [_plusButtonsView hideAnimated:YES completionHandler:nil]; + else + [_plusButtonsView showAnimated:YES completionHandler:nil]; +} + +#pragma mark - Dealloc + +- (void)dealloc +{ + NSLog(@"%s [Line %d]", __PRETTY_FUNCTION__, __LINE__); +} + +#pragma mark - Appearing + +- (void)viewWillLayoutSubviews +{ + [super viewWillLayoutSubviews]; + + CGFloat topInset = 0.f; + if ([UIDevice currentDevice].systemVersion.floatValue >= 7.0) + { + topInset += (self.navigationController.navigationBarHidden ? 0.f : MIN(self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height)); + topInset += ([UIApplication sharedApplication].statusBarHidden ? 0.f : MIN([UIApplication sharedApplication].statusBarFrame.size.width, [UIApplication sharedApplication].statusBarFrame.size.height)); + } + _contentView.frame = CGRectMake(0.f, topInset, self.view.frame.size.width, self.view.frame.size.height-topInset); + + [_textLabel sizeToFit]; + _textLabel.center = CGPointMake(_contentView.frame.size.width/2, _contentView.frame.size.height-20.f-_textLabel.frame.size.height/2); + _textLabel.frame = CGRectIntegral(_textLabel.frame); + + // ----- + + BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation); + + CGFloat buttonSide = (isPortrait ? 64.f : 44.f); + CGFloat inset = (isPortrait ? 3.f : 2.f); + CGFloat buttonsFontSize = (isPortrait ? 30.f : 20.f); + CGFloat plusButtonFontSize = buttonsFontSize*1.5; + + _plusButtonsView.buttonInset = UIEdgeInsetsMake(inset, inset, inset, inset); + _plusButtonsView.contentInset = UIEdgeInsetsMake(inset, inset, inset, inset); + [_plusButtonsView setButtonsTitleFont:[UIFont boldSystemFontOfSize:buttonsFontSize]]; + + _plusButtonsView.plusButton.titleLabel.font = [UIFont systemFontOfSize:plusButtonFontSize]; + _plusButtonsView.plusButton.titleOffset = CGPointMake(0.f, -plusButtonFontSize*0.1); + + _plusButtonsView.buttonsSize = CGSizeMake(buttonSide, buttonSide); + [_plusButtonsView setButtonsLayerCornerRadius:buttonSide/2]; + [_plusButtonsView setButtonsLayerBorderColor:[UIColor colorWithRed:0.f green:0.f blue:0.f alpha:0.1] borderWidth:1.f]; + [_plusButtonsView setButtonsLayerMasksToBounds:YES]; + [_plusButtonsView setButtonsBackgroundColor:[UIColor colorWithRed:0.f green:0.5 blue:1.f alpha:1.f] forState:UIControlStateNormal]; + [_plusButtonsView setButtonsBackgroundColor:[UIColor colorWithRed:0.2 green:0.7 blue:1.f alpha:1.f] forState:UIControlStateHighlighted]; + [_plusButtonsView setButtonsBackgroundColor:[UIColor colorWithRed:0.2 green:0.7 blue:1.f alpha:1.f] forState:UIControlStateHighlighted|UIControlStateSelected]; +} + +@end diff --git a/Demo/LGPlusButtonsViewDemo/TableViewController.h b/Demo/LGPlusButtonsViewDemo/TableViewController.h new file mode 100644 index 0000000..fe8505a --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/TableViewController.h @@ -0,0 +1,13 @@ +// +// TableViewController.h +// LGPlusButtonsViewDemo +// +// Created by Grigory Lutkov on 26.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import + +@interface TableViewController : UITableViewController + +@end diff --git a/Demo/LGPlusButtonsViewDemo/TableViewController.m b/Demo/LGPlusButtonsViewDemo/TableViewController.m new file mode 100644 index 0000000..c4fa3da --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/TableViewController.m @@ -0,0 +1,79 @@ +// +// TableViewController.m +// LGPlusButtonsViewDemo +// +// Created by Grigory Lutkov on 26.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import "TableViewController.h" +#import "PlusViewController.h" +#import "PlusScrollViewController.h" + +@interface TableViewController () + +@property (strong, nonatomic) NSArray *titlesArray; + +@end + +@implementation TableViewController + +- (id)init +{ + self = [super initWithStyle:UITableViewStylePlain]; + if (self) + { + self.title = @"LGPlusButtonsView"; + + _titlesArray = @[@"UIView + Variant 1", + @"UIScrollView + Variant 2"]; + + [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; + } + return self; +} + +#pragma mark - UITableView DataSource + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return _titlesArray.count; +} + +#pragma mark - UITableView Delegate + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; + + cell.textLabel.font = [UIFont systemFontOfSize:16.f]; + cell.textLabel.text = _titlesArray[indexPath.row]; + + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return 44.f; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.row == 0) + { + PlusViewController *viewController = [[PlusViewController alloc] initWithTitle:_titlesArray[indexPath.row]]; + [self.navigationController pushViewController:viewController animated:YES]; + } + else if (indexPath.row == 1) + { + PlusScrollViewController *viewController = [[PlusScrollViewController alloc] initWithTitle:_titlesArray[indexPath.row]]; + [self.navigationController pushViewController:viewController animated:YES]; + } +} + +@end diff --git a/Demo/LGPlusButtonsViewDemo/main.m b/Demo/LGPlusButtonsViewDemo/main.m new file mode 100644 index 0000000..97a1ce5 --- /dev/null +++ b/Demo/LGPlusButtonsViewDemo/main.m @@ -0,0 +1,16 @@ +// +// main.m +// LGPlusButtonsViewDemo +// +// Created by Admin on 26.02.15. +// Copyright (c) 2015 Grigory Lutkov. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/Demo/Podfile b/Demo/Podfile new file mode 100644 index 0000000..2cb59d4 --- /dev/null +++ b/Demo/Podfile @@ -0,0 +1,11 @@ +source 'https://github.com/CocoaPods/Specs.git' + +platform :ios, '6.0' +inhibit_all_warnings! + +xcodeproj 'LGPlusButtonsViewDemo' + +target 'LGPlusButtonsViewDemo' do + pod 'LGPlusButtonsView', :path => '../' + pod 'LGDrawer', '~> 1.0.0' +end diff --git a/Demo/Podfile.lock b/Demo/Podfile.lock new file mode 100644 index 0000000..b247723 --- /dev/null +++ b/Demo/Podfile.lock @@ -0,0 +1,19 @@ +PODS: + - LGDrawer (1.0.0) + - LGPlusButtonsView (1.0.0) + +DEPENDENCIES: + - LGDrawer (from `../../LGDrawer`) + - LGPlusButtonsView (from `../`) + +EXTERNAL SOURCES: + LGDrawer: + :path: ../../LGDrawer + LGPlusButtonsView: + :path: ../ + +SPEC CHECKSUMS: + LGDrawer: 7ceea97b27a6b23e8eb691210ca180c897025513 + LGPlusButtonsView: a3a7d0c47f99dcce30911541f8d2d255244ab645 + +COCOAPODS: 0.37.2 diff --git a/Demo/podsInstall.command b/Demo/podsInstall.command new file mode 100644 index 0000000..3c76888 --- /dev/null +++ b/Demo/podsInstall.command @@ -0,0 +1,5 @@ +#!/bin/sh + +cd "$(dirname "$0")" + +pod install diff --git a/Demo/podsUpdate.command b/Demo/podsUpdate.command new file mode 100644 index 0000000..f48a821 --- /dev/null +++ b/Demo/podsUpdate.command @@ -0,0 +1,5 @@ +#!/bin/sh + +cd "$(dirname "$0")" + +pod update diff --git a/LGPlusButtonsView.podspec b/LGPlusButtonsView.podspec new file mode 100644 index 0000000..4b28645 --- /dev/null +++ b/LGPlusButtonsView.podspec @@ -0,0 +1,16 @@ +Pod::Spec.new do |s| + + s.name = 'LGPlusButtonsView' + s.version = '1.0.0' + s.platform = :ios, '6.0' + s.license = 'MIT' + s.homepage = 'https://github.com/Friend-LGA/LGPlusButtonsView' + s.author = { 'Grigory Lutkov' => 'Friend.LGA@gmail.com' } + s.source = { :git => 'https://github.com/Friend-LGA/LGPlusButtonsView.git', :tag => s.version } + s.summary = 'iOS implementation of Google , that shows more options' + + s.requires_arc = true + + s.source_files = 'LGPlusButtonsView/*.{h,m}' + +end diff --git a/LGPlusButtonsView/LGPlusButton.h b/LGPlusButtonsView/LGPlusButton.h new file mode 100644 index 0000000..039d22e --- /dev/null +++ b/LGPlusButtonsView/LGPlusButton.h @@ -0,0 +1,56 @@ +// +// LGPlusButton.h +// LGPlusButtonsView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGPlusButtonsView) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#import + +@interface LGPlusButton : UIButton + +@property (assign, nonatomic) CGPoint titleOffset; +@property (assign, nonatomic) CGPoint imageOffset; + +- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state; + +/** Unavailable, use titleOffset and imageOffset instead */ +- (void)setContentHorizontalAlignment:(UIControlContentHorizontalAlignment)contentHorizontalAlignment __attribute__((unavailable("Use titleOffset and imageOffset instead"))); +/** Unavailable, use titleOffset and imageOffset instead */ +- (UIControlContentHorizontalAlignment)contentHorizontalAlignment __attribute__((unavailable("Use titleOffset and imageOffset instead"))); +/** Unavailable, use titleOffset and imageOffset instead */ +- (void)setContentVerticalAlignment:(UIControlContentVerticalAlignment)contentVerticalAlignment __attribute__((unavailable("Use titleOffset and imageOffset instead"))); +/** Unavailable, use titleOffset and imageOffset instead */ +- (UIControlContentVerticalAlignment)contentVerticalAlignment __attribute__((unavailable("Use titleOffset and imageOffset instead"))); +/** Unavailable, use titleOffset and imageOffset instead */ +- (void)setTitleEdgeInsets:(UIEdgeInsets)titleEdgeInsets __attribute__((unavailable("Use titleOffset and imageOffset instead"))); +/** Unavailable, use titleOffset and imageOffset instead */ +- (UIEdgeInsets)titleEdgeInsets __attribute__((unavailable("Use titleOffset and imageOffset instead"))); +/** Unavailable, use titleOffset and imageOffset instead */ +- (void)setImageEdgeInsets:(UIEdgeInsets)imageEdgeInsets __attribute__((unavailable("Use titleOffset and imageOffset instead"))); +/** Unavailable, use titleOffset and imageOffset instead */ +- (UIEdgeInsets)imageEdgeInsets __attribute__((unavailable("Use titleOffset and imageOffset instead"))); + +@end diff --git a/LGPlusButtonsView/LGPlusButton.m b/LGPlusButtonsView/LGPlusButton.m new file mode 100644 index 0000000..55883bf --- /dev/null +++ b/LGPlusButtonsView/LGPlusButton.m @@ -0,0 +1,151 @@ +// +// LGPlusButton.m +// LGPlusButtonsView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGPlusButtonsView) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#import "LGPlusButton.h" + +// Do not forget about "protected" +@interface LGPlusButton () + +@property (assign, nonatomic, getter=isShowing) BOOL showing; + +@end + +@implementation LGPlusButton + +- (instancetype)init +{ + self = [super init]; + if (self) + { + self.backgroundColor = [UIColor clearColor]; + self.layer.anchorPoint = CGPointMake(0.5, 0.5); + + self.imageView.contentMode = UIViewContentModeScaleAspectFit; + + _titleOffset = CGPointZero; + _imageOffset = CGPointZero; + } + return self; +} + +#pragma mark - + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGFloat scaleX = [[self.layer valueForKeyPath:@"transform.scale.x"] floatValue]; + CGFloat scaleY = [[self.layer valueForKeyPath:@"transform.scale.y"] floatValue]; + + CGRect selfFrame = CGRectMake(0.f, 0.f, self.frame.size.width/scaleX, self.frame.size.height/scaleY); + + CGSize sizeToFit = CGSizeMake(selfFrame.size.width-self.contentEdgeInsets.left-self.contentEdgeInsets.right, + selfFrame.size.height-self.contentEdgeInsets.top-self.contentEdgeInsets.bottom); + + if (self.titleLabel.text.length) + { + CGSize titleLabelSize = [self.titleLabel sizeThatFits:sizeToFit]; + CGRect titleLabelFrame = CGRectMake(selfFrame.size.width/2-titleLabelSize.width/2+_titleOffset.x, + selfFrame.size.height/2-titleLabelSize.height/2+_titleOffset.y, + titleLabelSize.width, + titleLabelSize.height); + if ([UIScreen mainScreen].scale == 1.f) titleLabelFrame = CGRectIntegral(titleLabelFrame); + self.titleLabel.frame = titleLabelFrame; + } + + if (self.imageView.image) + { + CGSize imageViewSize = [self.imageView sizeThatFits:sizeToFit]; + CGRect imageViewFrame = CGRectMake(selfFrame.size.width/2-imageViewSize.width/2+_imageOffset.x, + selfFrame.size.height/2-imageViewSize.height/2+_imageOffset.y, + imageViewSize.width, + imageViewSize.height); + if ([UIScreen mainScreen].scale == 1.f) imageViewFrame = CGRectIntegral(imageViewFrame); + self.imageView.frame = imageViewFrame; + } +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + CGSize titleLabelSize = (self.titleLabel.text.length ? [self.titleLabel sizeThatFits:size] : CGSizeZero); + CGSize imageViewSize = (self.imageView.image ? [self.imageView sizeThatFits:size] : CGSizeZero); + + CGSize resultSize = CGSizeMake(MAX(titleLabelSize.width, imageViewSize.width)+self.contentEdgeInsets.left+self.contentEdgeInsets.right, + MAX(titleLabelSize.height, imageViewSize.height)+self.contentEdgeInsets.top+self.contentEdgeInsets.bottom); + + return resultSize; +} + +#pragma mark - Setters and Getters + +- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state +{ + [self setBackgroundImage:[LGPlusButton image1x1WithColor:backgroundColor] forState:state]; +} + +- (void)setTitleOffset:(CGPoint)titleOffset +{ + if (!CGPointEqualToPoint(_titleOffset, titleOffset)) + { + _titleOffset = titleOffset; + + [self layoutSubviews]; + } +} + +- (void)setImageOffset:(CGPoint)imageOffset +{ + if (!CGPointEqualToPoint(_imageOffset, imageOffset)) + { + _imageOffset = imageOffset; + + [self layoutSubviews]; + } +} + +#pragma mark - Support + ++ (UIImage *)image1x1WithColor:(UIColor *)color +{ + CGRect rect = CGRectMake(0.f, 0.f, 1.f, 1.f); + + UIGraphicsBeginImageContext(rect.size); + + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGContextSetFillColorWithColor(context, color.CGColor); + CGContextFillRect(context, rect); + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; +} + +@end diff --git a/LGPlusButtonsView/LGPlusButtonsView.h b/LGPlusButtonsView/LGPlusButtonsView.h new file mode 100644 index 0000000..1d3a8d5 --- /dev/null +++ b/LGPlusButtonsView/LGPlusButtonsView.h @@ -0,0 +1,184 @@ +// +// LGPlusButtonsView.h +// LGPlusButtonsView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGPlusButtonsView) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#import +#import "LGPlusButton.h" + +@class LGPlusButtonsView; + +@protocol LGPlusButtonsViewDelegate + +@optional + +- (void)plusButtonsView:(LGPlusButtonsView *)plusButtonsView buttonPressedWithTitle:(NSString *)title description:(NSString *)description index:(NSUInteger)index; +- (void)plusButtonsViewPlusButtonPressed:(LGPlusButtonsView *)plusButtonsView; + +@end + +@interface LGPlusButtonsView : UIView + +typedef enum +{ + LGPlusButtonsViewPositionBottomRight = 0, + LGPlusButtonsViewPositionBottomLeft = 1, + LGPlusButtonsViewPositionTopRight = 2, + LGPlusButtonsViewPositionTopLeft = 3 +} +LGPlusButtonsViewPosition; + +typedef enum +{ + LGPlusButtonsAppearingAnimationTypeNone = 0, + LGPlusButtonsAppearingAnimationTypeCrossDissolve = 1, + LGPlusButtonsAppearingAnimationTypeCrossDissolveAndSlideHorizontal = 2, + LGPlusButtonsAppearingAnimationTypeCrossDissolveAndSlideVertical = 3, + LGPlusButtonsAppearingAnimationTypeCrossDissolveAndPop = 4 +} +LGPlusButtonsAppearingAnimationType; + +typedef enum +{ + LGPlusButtonAnimationTypeNone = 0, + LGPlusButtonAnimationTypeRotate = 1, + LGPlusButtonAnimationTypeCrossDissolve = 2 +} +LGPlusButtonAnimationType; + +@property (assign, nonatomic, getter=isShowing) BOOL showing; +@property (assign, nonatomic, getter=isShowWhenScrolling) BOOL showWhenScrolling; + +@property (strong, nonatomic) LGPlusButton *plusButton; + +/** First is plusButton */ +@property (strong, nonatomic) NSMutableArray *buttons; +/** First is plusButton description */ +@property (strong, nonatomic) NSMutableArray *descriptions; + +@property (assign, nonatomic) UIEdgeInsets contentInset; +@property (assign, nonatomic) UIEdgeInsets buttonInset; +@property (assign, nonatomic) CGSize buttonsSize; +@property (assign, nonatomic) CGSize plusButtonSize; +/** Description horizontal offset from button, default is 6.f */ +@property (assign, nonatomic) CGFloat descriptionOffsetX; + +@property (assign, nonatomic) LGPlusButtonsAppearingAnimationType appearingAnimationType; +@property (assign, nonatomic) LGPlusButtonsAppearingAnimationType buttonsAppearingAnimationType; +@property (assign, nonatomic) LGPlusButtonAnimationType plusButtonAnimationType; +@property (assign, nonatomic) LGPlusButtonsViewPosition position; + +/** Do not forget about weak referens to self */ +@property (strong, nonatomic) void (^actionHandler)(LGPlusButtonsView *plusButtonView, NSString *title, NSString *description, NSUInteger index); +/** Do not forget about weak referens to self */ +@property (strong, nonatomic) void (^plusButtonActionHandler)(LGPlusButtonsView *plusButtonView); + +@property (assign, nonatomic) id delegate; + +- (instancetype)initWithView:(UIView *)view + numberOfButtons:(NSUInteger)numberOfButtons + showsPlusButton:(BOOL)showsPlusButton; + ++ (instancetype)plusButtonsViewWithView:(UIView *)view + numberOfButtons:(NSUInteger)numberOfButtons + showsPlusButton:(BOOL)showsPlusButton; + +#pragma mark - + +/** Do not forget about weak referens to self for actionHandler and plusButtonActionHandler blocks */ +- (instancetype)initWithView:(UIView *)view + numberOfButtons:(NSUInteger)numberOfButtons + showsPlusButton:(BOOL)showsPlusButton + actionHandler:(void(^)(LGPlusButtonsView *plusButtonView, NSString *title, NSString *description, NSUInteger index))actionHandler + plusButtonActionHandler:(void(^)(LGPlusButtonsView *plusButtonView))plusButtonActionHandler; + +/** Do not forget about weak referens to self for actionHandler and plusButtonActionHandler blocks */ ++ (instancetype)plusButtonsViewWithView:(UIView *)view + numberOfButtons:(NSUInteger)numberOfButtons + showsPlusButton:(BOOL)showsPlusButton + actionHandler:(void(^)(LGPlusButtonsView *plusButtonView, NSString *title, NSString *description, NSUInteger index))actionHandler + plusButtonActionHandler:(void(^)(LGPlusButtonsView *plusButtonView))plusButtonActionHandler; + +#pragma mark - + +- (instancetype)initWithView:(UIView *)view + numberOfButtons:(NSUInteger)numberOfButtons + showsPlusButton:(BOOL)showsPlusButton + delegate:(id)delegate; + ++ (instancetype)plusButtonsViewWithView:(UIView *)view + numberOfButtons:(NSUInteger)numberOfButtons + showsPlusButton:(BOOL)showsPlusButton + delegate:(id)delegate; + +#pragma mark - + +- (void)setButtonsTitles:(NSArray *)titles forState:(UIControlState)state; +- (void)setButtonsTitleColor:(UIColor *)titleColor forState:(UIControlState)state; +- (void)setButtonsImage:(UIImage *)image forState:(UIControlState)state; +- (void)setButtonsBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state; +- (void)setButtonsBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state; +- (void)setButtonsTitleFont:(UIFont *)font; + +#pragma mark - + +- (void)setDescriptionsTexts:(NSArray *)texts; +- (void)setDescriptionsTextColor:(UIColor *)textColor; +- (void)setDescriptionsBackgroundColor:(UIColor *)backgroundColor; +- (void)setDescriptionsFont:(UIFont *)font; + +#pragma mark - + +- (void)setButtonsClipsToBounds:(BOOL)clipsToBounds; +- (void)setButtonsContentEdgeInsets:(UIEdgeInsets)contentEdgeInsets; +- (void)setButtonsAdjustsImageWhenHighlighted:(BOOL)adjustsImageWhenHighlighted; + +#pragma mark - + +- (void)setButtonsLayerMasksToBounds:(BOOL)masksToBounds; +- (void)setButtonsLayerCornerRadius:(CGFloat)cornerRadius; +- (void)setButtonsLayerBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth; +- (void)setButtonsLayerShadowColor:(UIColor *)shadowColor shadowOpacity:(float)shadowOpacity shadowOffset:(CGSize)shadowOffset shadowRadius:(CGFloat)shadowRadius; + +#pragma mark - + +- (void)showAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler; +- (void)hideAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler; + +- (void)showButtonsAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler; +- (void)hideButtonsAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler; + +#pragma mark - + +/** Unavailable, use +plusButtonsViewWithView... instead */ ++ (instancetype)new __attribute__((unavailable("use +plusButtonsViewWithView... instead"))); +/** Unavailable, use -initWithView... instead */ +- (instancetype)init __attribute__((unavailable("use -initWithView... instead"))); +/** Unavailable, use -initWithView... instead */ +- (instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("use -initWithView... instead"))); + +@end diff --git a/LGPlusButtonsView/LGPlusButtonsView.m b/LGPlusButtonsView/LGPlusButtonsView.m new file mode 100644 index 0000000..9dbaff5 --- /dev/null +++ b/LGPlusButtonsView/LGPlusButtonsView.m @@ -0,0 +1,1464 @@ +// +// LGPlusButtonsView.m +// LGPlusButtonsView +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 Grigory Lutkov +// (https://github.com/Friend-LGA/LGPlusButtonsView) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#import "LGPlusButtonsView.h" + +#define kLGPlusButtonsViewDegreesToRadians(d) ((d) * M_PI / 180) + +@interface WrapperView : UIView + +@property (assign, nonatomic) UIView *actionView; + +@end + +@implementation WrapperView + +- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event +{ + //NSLog(@"\nself = %@\nsuper = %@\nactionView = %@\nsubviews = %@\n\n", self, [super hitTest:point withEvent:event], _actionView, self.subviews); + + UIView *superView = [super hitTest:point withEvent:event]; + + UIView *view; + if (superView) + view = superView; + else if (_actionView) + view = _actionView; + + return view; +} + +@end + +#pragma mark - + +@interface LGPlusButton (protected) + +@property (assign, nonatomic, getter=isShowing) BOOL showing; + +@end + +#pragma mark - + +@interface LGPlusButtonsView () + +typedef enum +{ + LGPlusButtondescriptionsPositionLeft = 0, + LGPlusButtondescriptionsPositionRight = 1 +} +LGPlusButtonDescriptionsPosition; + +@property (assign, nonatomic, getter=isObserversAdded) BOOL observersAdded; + +@property (assign, nonatomic) LGPlusButtonDescriptionsPosition descriptionsPosition; + +@property (assign, nonatomic) UIView *parentView; + +@property (strong, nonatomic) NSMutableArray *buttonWrapperViews1; +@property (strong, nonatomic) NSMutableArray *buttonWrapperViews2; +@property (strong, nonatomic) NSMutableArray *descriptionWrapperViews; + +@property (strong, nonatomic) WrapperView *plusButtonWrapperView1; +@property (strong, nonatomic) WrapperView *plusButtonWrapperView2; +@property (strong, nonatomic) UILabel *plusDescription; +@property (strong, nonatomic) WrapperView *plusDescriptionWrapperView; + +@property (assign, nonatomic) CGFloat offsetY; +@property (assign, nonatomic) CGFloat tempOffsetY; +@property (assign, nonatomic) CGFloat tempDiff; + +@property (assign, nonatomic, getter=isShowsPlusButton) BOOL showsPlusButton; + +@end + +@implementation LGPlusButtonsView + +- (instancetype)initWithView:(UIView *)view + numberOfButtons:(NSUInteger)numberOfButtons + showsPlusButton:(BOOL)showsPlusButton +{ + self = [super init]; + if (self) + { + _parentView = view; + _showWhenScrolling = YES; + _appearingAnimationType = LGPlusButtonsAppearingAnimationTypeCrossDissolveAndSlideVertical; + _buttonsAppearingAnimationType = LGPlusButtonsAppearingAnimationTypeCrossDissolveAndSlideHorizontal; + _showsPlusButton = showsPlusButton; + _descriptionOffsetX = 6.f; + + // ----- + + self.backgroundColor = [UIColor clearColor]; + self.hidden = YES; + + // ----- + + _buttonWrapperViews1 = [NSMutableArray new]; + _buttonWrapperViews2 = [NSMutableArray new]; + _buttons = [NSMutableArray new]; + + if (self.isShowsPlusButton) + { + _plusButtonWrapperView1 = [WrapperView new]; + _plusButtonWrapperView1.backgroundColor = [UIColor clearColor]; + _plusButtonWrapperView1.clipsToBounds = NO; + _plusButtonWrapperView1.layer.masksToBounds = NO; + _plusButtonWrapperView1.layer.anchorPoint = CGPointMake(0.5, 0.5); + _plusButtonWrapperView1.userInteractionEnabled = YES; + [self addSubview:_plusButtonWrapperView1]; + + [_buttonWrapperViews1 addObject:_plusButtonWrapperView1]; + + _plusButtonWrapperView2 = [WrapperView new]; + _plusButtonWrapperView2.backgroundColor = [UIColor clearColor]; + _plusButtonWrapperView2.clipsToBounds = NO; + _plusButtonWrapperView2.layer.masksToBounds = NO; + _plusButtonWrapperView2.layer.anchorPoint = CGPointMake(0.5, 0.5); + _plusButtonWrapperView2.userInteractionEnabled = YES; + [_plusButtonWrapperView1 addSubview:_plusButtonWrapperView2]; + + [_buttonWrapperViews2 addObject:_plusButtonWrapperView2]; + + _plusButton = [LGPlusButton new]; + [_plusButton addTarget:self action:@selector(plusButtonAction:) forControlEvents:UIControlEventTouchUpInside]; + [_plusButtonWrapperView2 addSubview:_plusButton]; + + _plusButtonWrapperView2.actionView = _plusButton; + [_buttons addObject:_plusButton]; + } + + // ----- + + for (NSUInteger i=0; i)delegate +{ + self = [self initWithView:view numberOfButtons:numberOfButtons showsPlusButton:showsPlusButton]; + if (self) + { + _delegate = delegate; + } + return self; +} + ++ (instancetype)plusButtonsViewWithView:(UIView *)view + numberOfButtons:(NSUInteger)numberOfButtons + showsPlusButton:(BOOL)showsPlusButton + delegate:(id)delegate +{ + return [[self alloc] initWithView:view + numberOfButtons:numberOfButtons + showsPlusButton:showsPlusButton + delegate:delegate]; +} + +#pragma mark - Dealloc + +- (void)dealloc +{ +#if DEBUG + NSLog(@"%s [Line %d]", __PRETTY_FUNCTION__, __LINE__); +#endif +} + +#pragma mark - + +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + if (!newSuperview) + [self removeObservers]; + else + [self addObservers]; +} + +#pragma mark - Setters and Getters + +- (void)setButtonsTitles:(NSArray *)titles forState:(UIControlState)state +{ + BOOL isChanged = NO; + + for (NSUInteger i=0; i<_buttons.count; i++) + { + LGPlusButton *button = _buttons[i]; + + if (![button.titleLabel.text isEqualToString:titles[i]]) + { + [button setTitle:titles[i] forState:state]; + + isChanged = YES; + } + } + + if (isChanged) [self layoutInvalidate]; +} + +- (void)setButtonsTitleColor:(UIColor *)titleColor forState:(UIControlState)state +{ + for (LGPlusButton *button in _buttons) + [button setTitleColor:titleColor forState:state]; +} + +- (void)setButtonsImage:(UIImage *)image forState:(UIControlState)state +{ + BOOL isChanged = NO; + + for (LGPlusButton *button in _buttons) + { + if (!CGSizeEqualToSize(button.imageView.image.size, image.size)) + isChanged = YES; + + [button setImage:image forState:state]; + } + + if (isChanged) [self layoutInvalidate]; +} + +- (void)setButtonsBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state +{ + for (LGPlusButton *button in _buttons) + [button setBackgroundImage:backgroundImage forState:state]; +} + +- (void)setButtonsBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state +{ + for (LGPlusButton *button in _buttons) + [button setBackgroundColor:backgroundColor forState:state]; +} + +- (void)setButtonsTitleFont:(UIFont *)font +{ + BOOL isChanged = NO; + + for (LGPlusButton *button in _buttons) + if (![button.titleLabel.font isEqual:font]) + { + button.titleLabel.font = font; + + isChanged = YES; + } + + if (isChanged) [self layoutInvalidate]; +} + +#pragma mark - + +- (void)setDescriptionsTexts:(NSArray *)texts +{ + BOOL isChanged = NO; + + for (NSUInteger i=0; i<_descriptions.count; i++) + { + UILabel *label = _descriptions[i]; + + if (![label.text isEqualToString:texts[i]]) + { + label.text = texts[i]; + + isChanged = YES; + } + } + + if (isChanged) [self layoutInvalidate]; +} + +- (void)setDescriptionsTextColor:(UIColor *)textColor +{ + for (UILabel *label in _descriptions) + label.textColor = textColor; +} + +- (void)setDescriptionsBackgroundColor:(UIColor *)backgroundColor +{ + for (UILabel *label in _descriptions) + label.backgroundColor = backgroundColor; +} + +- (void)setDescriptionsFont:(UIFont *)font +{ + BOOL isChanged = NO; + + for (UILabel *label in _descriptions) + if (![label.font isEqual:font]) + { + label.font = font; + + isChanged = YES; + } + + if (isChanged) [self layoutInvalidate]; +} + +- (void)setDescriptionOffsetX:(CGFloat)descriptionOffsetX +{ + if (_descriptionOffsetX != descriptionOffsetX) + { + _descriptionOffsetX = descriptionOffsetX; + + [self layoutInvalidate]; + } +} + +#pragma mark - + +- (void)setButtonsClipsToBounds:(BOOL)clipsToBounds +{ + for (LGPlusButton *button in _buttons) + button.clipsToBounds = clipsToBounds; +} + +- (void)setButtonsContentEdgeInsets:(UIEdgeInsets)contentEdgeInsets +{ + BOOL isChanged = NO; + + for (LGPlusButton *button in _buttons) + if (!UIEdgeInsetsEqualToEdgeInsets(button.contentEdgeInsets, contentEdgeInsets)) + { + button.contentEdgeInsets = contentEdgeInsets; + + isChanged = YES; + } + + if (isChanged) [self layoutInvalidate]; +} + +- (void)setButtonsAdjustsImageWhenHighlighted:(BOOL)adjustsImageWhenHighlighted +{ + for (LGPlusButton *button in _buttons) + button.adjustsImageWhenHighlighted = adjustsImageWhenHighlighted; +} + +#pragma mark - + +- (void)setButtonsLayerMasksToBounds:(BOOL)masksToBounds +{ + for (LGPlusButton *button in _buttons) + button.layer.masksToBounds = masksToBounds; +} + +- (void)setButtonsLayerCornerRadius:(CGFloat)cornerRadius +{ + for (LGPlusButton *button in _buttons) + button.layer.cornerRadius = cornerRadius; +} + +- (void)setButtonsLayerBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth +{ + for (LGPlusButton *button in _buttons) + { + button.layer.borderColor = borderColor.CGColor; + button.layer.borderWidth = borderWidth; + } +} + +- (void)setButtonsLayerShadowColor:(UIColor *)shadowColor shadowOpacity:(float)shadowOpacity shadowOffset:(CGSize)shadowOffset shadowRadius:(CGFloat)shadowRadius +{ + for (LGPlusButton *button in _buttons) + { + button.layer.shadowColor = shadowColor.CGColor; + button.layer.shadowOpacity = shadowOpacity; + button.layer.shadowOffset = shadowOffset; + button.layer.shadowRadius = shadowRadius; + } +} + +#pragma mark - + +- (void)setContentInset:(UIEdgeInsets)contentInset +{ + if (!UIEdgeInsetsEqualToEdgeInsets(_contentInset, contentInset)) + { + _contentInset = contentInset; + + [self layoutInvalidate]; + } +} + +- (void)setButtonInset:(UIEdgeInsets)buttonInset +{ + if (!UIEdgeInsetsEqualToEdgeInsets(_buttonInset, buttonInset)) + { + _buttonInset = buttonInset; + + [self layoutInvalidate]; + } +} + +- (void)setButtonsSize:(CGSize)buttonsSize +{ + if (!CGSizeEqualToSize(_buttonsSize, buttonsSize)) + { + _buttonsSize = buttonsSize; + + [self layoutInvalidate]; + } +} + +- (void)setPlusButtonSize:(CGSize)plusButtonSize +{ + if (!CGSizeEqualToSize(_plusButtonSize, plusButtonSize)) + { + _plusButtonSize = plusButtonSize; + + [self layoutInvalidate]; + } +} + +- (void)setPosition:(LGPlusButtonsViewPosition)position +{ + if (_position != position) + { + _position = position; + + if (_position == LGPlusButtonsViewPositionBottomRight || _position == LGPlusButtonsViewPositionTopRight) + _descriptionsPosition = LGPlusButtondescriptionsPositionLeft; + else + _descriptionsPosition = LGPlusButtondescriptionsPositionRight; + + [self layoutInvalidate]; + } +} + +#pragma mark - + +- (void)layoutInvalidate +{ + if (self.superview) + { + UIEdgeInsets parentInset = UIEdgeInsetsZero; + CGPoint parentOffset = CGPointZero; + + if ([_parentView isKindOfClass:[UIScrollView class]]) + { + UIScrollView *parentScrollView = (UIScrollView *)_parentView; + + parentInset = parentScrollView.contentInset; + parentOffset = parentScrollView.contentOffset; + } + + // ----- + + NSMutableArray *buttonsSizeArray = [NSMutableArray new]; + + CGSize selfSize = CGSizeMake(_buttonInset.left+_buttonInset.right+_contentInset.left+_contentInset.right, + (_buttonInset.left+_buttonInset.right)*_buttons.count+_contentInset.top+_contentInset.bottom); + + if (!CGSizeEqualToSize(_buttonsSize, CGSizeZero)) + { + if (!CGSizeEqualToSize(_plusButtonSize, CGSizeZero) && self.isShowsPlusButton) + { + selfSize.width += MAX(_plusButtonSize.width, _buttonsSize.width); + selfSize.height += _plusButtonSize.height+(_buttonsSize.height*_buttons.count-1); + } + else + { + selfSize.width += _buttonsSize.width; + selfSize.height += _buttonsSize.height*_buttons.count; + } + } + else + { + CGFloat width = 0.f; + + for (NSUInteger i=0; i<_buttons.count; i++) + { + if (i == 0 && !CGSizeEqualToSize(_plusButtonSize, CGSizeZero) && self.isShowsPlusButton) + { + [buttonsSizeArray addObject:NSStringFromCGSize(_plusButtonSize)]; + + width = MAX(width, _plusButtonSize.width); + selfSize.height += _plusButtonSize.height; + } + else + { + LGPlusButton *button = _buttons[i]; + + CGSize buttonSize = [button sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; + + [buttonsSizeArray addObject:NSStringFromCGSize(buttonSize)]; + + width = MAX(width, buttonSize.width); + selfSize.height += buttonSize.height; + } + } + + selfSize.width += width; + } + + // ----- + + CGPoint selfOrigin = CGPointZero; + if (_position == LGPlusButtonsViewPositionBottomRight) + { + selfOrigin = CGPointMake(_parentView.frame.size.width-parentInset.right-selfSize.width+parentOffset.x, + _parentView.frame.size.height-parentInset.bottom-selfSize.height+parentOffset.y); + } + else if (_position == LGPlusButtonsViewPositionBottomLeft) + { + selfOrigin = CGPointMake(parentInset.left+parentOffset.x, + _parentView.frame.size.height-parentInset.bottom-selfSize.height+parentOffset.y); + } + else if (_position == LGPlusButtonsViewPositionTopRight) + { + selfOrigin = CGPointMake(_parentView.frame.size.width-parentInset.right-selfSize.width+parentOffset.x, + parentInset.top+parentOffset.y); + } + else if (_position == LGPlusButtonsViewPositionTopLeft) + { + selfOrigin = CGPointMake(parentInset.left+parentOffset.x, + parentInset.top+parentOffset.y); + } + + CGRect selfFrame = CGRectMake(selfOrigin.x, selfOrigin.y, selfSize.width, selfSize.height); + if ([UIScreen mainScreen].scale == 1.f) selfFrame = CGRectIntegral(selfFrame); + self.frame = selfFrame; + + // ----- + + for (NSUInteger i=0; i<_buttons.count; i++) + { + WrapperView *buttonWrapperView1 = _buttonWrapperViews1[i]; + WrapperView *buttonWrapperView2 = _buttonWrapperViews2[i]; + LGPlusButton *button = _buttons[i]; + + CGRect buttonFrame = CGRectZero; + CGSize buttonSize = CGSizeZero; + + if (i == 0 && !CGSizeEqualToSize(_plusButtonSize, CGSizeZero) && self.isShowsPlusButton) + buttonSize = _plusButtonSize; + else if (!CGSizeEqualToSize(_buttonsSize, CGSizeZero)) + buttonSize = _buttonsSize; + else + buttonSize = CGSizeFromString(buttonsSizeArray[i]); + + if (i == 0) + { + if (_position == LGPlusButtonsViewPositionBottomRight) + { + buttonFrame = CGRectMake(selfFrame.size.width-_contentInset.right-_buttonInset.right-buttonSize.width, + selfFrame.size.height-_contentInset.bottom-_buttonInset.bottom-buttonSize.height, + buttonSize.width, + buttonSize.height); + } + else if (_position == LGPlusButtonsViewPositionBottomLeft) + { + buttonFrame = CGRectMake(_contentInset.left+_buttonInset.left, + selfFrame.size.height-_contentInset.bottom-_buttonInset.bottom-buttonSize.height, + buttonSize.width, + buttonSize.height); + } + else if (_position == LGPlusButtonsViewPositionTopRight) + { + buttonFrame = CGRectMake(selfFrame.size.width-_contentInset.right-_buttonInset.right-buttonSize.width, + _contentInset.top+_buttonInset.top, + buttonSize.width, + buttonSize.height); + } + else if (_position == LGPlusButtonsViewPositionTopLeft) + { + buttonFrame = CGRectMake(_contentInset.left+_buttonInset.left, + _contentInset.top+_buttonInset.top, + buttonSize.width, + buttonSize.height); + } + } + else + { + WrapperView *previousWrapperView1 = _buttonWrapperViews1[i-1]; + + if (_position == LGPlusButtonsViewPositionBottomRight) + { + buttonFrame = CGRectMake(selfFrame.size.width-_contentInset.right-_buttonInset.right-buttonSize.width, + previousWrapperView1.frame.origin.y-_buttonInset.top-_buttonInset.bottom-buttonSize.height, + buttonSize.width, + buttonSize.height); + } + else if (_position == LGPlusButtonsViewPositionBottomLeft) + { + buttonFrame = CGRectMake(_contentInset.left+_buttonInset.left, + previousWrapperView1.frame.origin.y-_buttonInset.top-_buttonInset.bottom-buttonSize.height, + buttonSize.width, + buttonSize.height); + } + else if (_position == LGPlusButtonsViewPositionTopRight) + { + buttonFrame = CGRectMake(selfFrame.size.width-_contentInset.right-_buttonInset.right-buttonSize.width, + previousWrapperView1.frame.origin.y+previousWrapperView1.frame.size.height+_buttonInset.bottom+_buttonInset.top, + buttonSize.width, + buttonSize.height); + } + else if (_position == LGPlusButtonsViewPositionTopLeft) + { + buttonFrame = CGRectMake(_contentInset.left+_buttonInset.left, + previousWrapperView1.frame.origin.y+previousWrapperView1.frame.size.height+_buttonInset.bottom+_buttonInset.top, + buttonSize.width, + buttonSize.height); + } + } + + if ([UIScreen mainScreen].scale == 1.f) buttonFrame = CGRectIntegral(buttonFrame); + buttonWrapperView1.transform = CGAffineTransformIdentity; + buttonWrapperView1.frame = buttonFrame; + + buttonWrapperView2.frame = CGRectMake(buttonWrapperView1.frame.size.width/2, buttonWrapperView1.frame.size.height/2, 0.f, 0.f); + button.frame = CGRectMake(-buttonWrapperView1.frame.size.width/2, -buttonWrapperView1.frame.size.height/2, buttonWrapperView1.frame.size.width, buttonWrapperView1.frame.size.height); + } + + // ----- + + for (NSUInteger i=0; i<_buttons.count; i++) + { + WrapperView *buttonWrapperView1 = _buttonWrapperViews1[i]; + LGPlusButton *button = _buttons[i]; + + WrapperView *descriptionWrapperView = _descriptionWrapperViews[i]; + UILabel *label = _descriptions[i]; + + if (label.text.length) + { + descriptionWrapperView.transform = CGAffineTransformIdentity; + descriptionWrapperView.frame = CGRectMake(buttonWrapperView1.frame.origin.x+button.contentEdgeInsets.left, + buttonWrapperView1.frame.origin.y+button.contentEdgeInsets.top, + buttonWrapperView1.frame.size.width-button.contentEdgeInsets.left-button.contentEdgeInsets.right, + buttonWrapperView1.frame.size.height-button.contentEdgeInsets.top-button.contentEdgeInsets.bottom); + CGFloat paddingWidth = 8.f; + CGFloat paddingHeight = 4.f; + + CGSize labelSize = [label sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; + + CGFloat originX; + if (_descriptionsPosition == LGPlusButtondescriptionsPositionLeft) + originX = -labelSize.width-_descriptionOffsetX-paddingWidth*2; + else + originX = descriptionWrapperView.frame.size.width+_descriptionOffsetX; + + CGRect labelFrame = CGRectMake(originX, + descriptionWrapperView.frame.size.height/2-labelSize.height/2-paddingHeight, + labelSize.width+paddingWidth*2, + labelSize.height+paddingHeight*2); + if ([UIScreen mainScreen].scale == 1.f) labelFrame = CGRectIntegral(labelFrame); + label.frame = labelFrame; + } + else + { + descriptionWrapperView.transform = CGAffineTransformIdentity; + descriptionWrapperView.frame = CGRectZero; + + label.frame = CGRectZero; + } + } + + // ----- + + for (NSUInteger i=0; i<_buttons.count; i++) + { + WrapperView *buttonWrapperView1 = _buttonWrapperViews1[i]; + LGPlusButton *button = _buttons[i]; + + if (!button.isShowing && CGAffineTransformEqualToTransform(buttonWrapperView1.transform, CGAffineTransformIdentity) && button.frame.size.width > 1.f && button.frame.size.height > 1.f) + [self hideAnimationsWithButtonAtIndex:i animationType:((i == 0 || !self.isShowsPlusButton) ? _appearingAnimationType : _buttonsAppearingAnimationType)]; + } + } +} + +- (void)updatePosition +{ + if (self.superview) + { + UIEdgeInsets parentInset = UIEdgeInsetsZero; + CGPoint parentOffset = CGPointZero; + + if ([_parentView isKindOfClass:[UIScrollView class]]) + { + UIScrollView *parentScrollView = (UIScrollView *)_parentView; + + parentInset = parentScrollView.contentInset; + parentOffset = parentScrollView.contentOffset; + } + + CGPoint selfOrigin = CGPointZero; + if (_position == LGPlusButtonsViewPositionBottomRight) + { + selfOrigin = CGPointMake(_parentView.frame.size.width-parentInset.right-self.frame.size.width+parentOffset.x, + _parentView.frame.size.height-parentInset.bottom-self.frame.size.height+parentOffset.y); + } + else if (_position == LGPlusButtonsViewPositionBottomLeft) + { + selfOrigin = CGPointMake(parentInset.left+parentOffset.x, + _parentView.frame.size.height-parentInset.bottom-self.frame.size.height+parentOffset.y); + } + else if (_position == LGPlusButtonsViewPositionTopRight) + { + selfOrigin = CGPointMake(_parentView.frame.size.width-parentInset.right-self.frame.size.width+parentOffset.x, + parentInset.top+parentOffset.y); + } + else if (_position == LGPlusButtonsViewPositionTopLeft) + { + selfOrigin = CGPointMake(parentInset.left+parentOffset.x, + parentInset.top+parentOffset.y); + } + + CGRect selfFrame = CGRectMake(selfOrigin.x, selfOrigin.y, self.frame.size.width, self.frame.size.height); + if ([UIScreen mainScreen].scale == 1.f) selfFrame = CGRectIntegral(selfFrame); + self.center = CGPointMake(selfFrame.origin.x+selfFrame.size.width/2, selfFrame.origin.y+selfFrame.size.height/2); + } +} + +#pragma mark - Actions + +- (void)plusButtonAction:(LGPlusButton *)button +{ + _plusButton.selected = !_plusButton.isSelected; + + if (_plusButton.isSelected) + { + [self selectPlusButtonViewWithAnimationType:_plusButtonAnimationType animated:YES completionHandler:nil]; + [self showButtonsAnimated:YES completionHandler:nil]; + } + else + { + [self deselectPlusButtonViewWithAnimationType:_plusButtonAnimationType animated:YES completionHandler:nil]; + [self hideButtonsAnimated:YES completionHandler:nil]; + } + + if (_plusButtonActionHandler) _plusButtonActionHandler(self); + + if (_delegate && [_delegate respondsToSelector:@selector(plusButtonsViewPlusButtonPressed:)]) + [_delegate plusButtonsViewPlusButtonPressed:self]; +} + +- (void)buttonAction:(LGPlusButton *)button +{ + NSUInteger index = [_buttons indexOfObject:button]; + + UILabel *descriptionLabel = _descriptions[index]; + + if (_actionHandler) _actionHandler(self, button.titleLabel.text, descriptionLabel.text, button.tag); + + if (_delegate && [_delegate respondsToSelector:@selector(plusButtonsView:buttonPressedWithTitle:description:index:)]) + [_delegate plusButtonsView:self buttonPressedWithTitle:button.titleLabel.text description:descriptionLabel.text index:button.tag]; +} + +#pragma mark - Animations + +- (void)showAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler +{ + if (!self.isShowing) + { + _showing = YES; + _plusButton.showing = YES; + + self.hidden = NO; + + NSTimeInterval delay = 0.03; + + if (self.isShowsPlusButton) + { + for (NSInteger i=0; i<_buttons.count; i++) + { + LGPlusButton *button = _buttons[i]; + + if (i == 0 || (i > 0 && button.isShowing)) + { + [self showButtonAtIndex:i + animationType:_appearingAnimationType + delay:delay*i + animated:animated + completionHandler:^(BOOL result) + { + if (completionHandler) completionHandler(); + }]; + } + } + } + else + { + for (NSInteger i=0; i<_buttons.count; i++) + { + LGPlusButton *button = _buttons[i]; + + button.showing = YES; + + [self showButtonAtIndex:i + animationType:_appearingAnimationType + delay:delay*i + animated:animated + completionHandler:^(BOOL result) + { + if (completionHandler) completionHandler(); + }]; + } + } + } +} + +- (void)hideAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler +{ + if (self.isShowing) + { + _showing = NO; + _plusButton.showing = NO; + + NSTimeInterval delay = 0.03; + + if (self.isShowsPlusButton) + { + for (NSInteger i=0; i<_buttons.count; i++) + { + LGPlusButton *button = _buttons[i]; + + if (i == 0 || (i > 0 && button.isShowing)) + { + __block NSUInteger index = i; + + [self hideButtonAtIndex:i + animationType:_appearingAnimationType + delay:delay*i + animated:animated + completionHandler:^(BOOL result) + { + if (result && index == _buttons.count-1) + self.hidden = YES; + + if (completionHandler) completionHandler(); + }]; + } + } + } + else + { + for (NSInteger i=0; i<_buttons.count; i++) + { + LGPlusButton *button = _buttons[i]; + + button.showing = NO; + + __block NSUInteger index = i; + + [self hideButtonAtIndex:i + animationType:_appearingAnimationType + delay:delay*i + animated:animated + completionHandler:^(BOOL result) + { + if (result && index == _buttons.count-1) + self.hidden = YES; + + if (completionHandler) completionHandler(); + }]; + } + } + } +} + +#pragma mark - + +- (void)showButtonsAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler +{ + if (self.isShowsPlusButton) + { + NSTimeInterval delay = 0.03; + + for (NSInteger i=1; i<_buttons.count; i++) + { + LGPlusButton *button = _buttons[i]; + + if (!button.isShowing) + { + button.showing = YES; + + if (_plusButton.isShowing) + { + [self showButtonAtIndex:i + animationType:_buttonsAppearingAnimationType + delay:delay*(i-1) + animated:animated + completionHandler:^(BOOL result) + { + if (completionHandler) completionHandler(); + }]; + } + else + { + [self hideButtonAtIndex:i + animationType:_appearingAnimationType + delay:delay*(i-1) + animated:animated + completionHandler:^(BOOL result) + { + if (completionHandler) completionHandler(); + }]; + } + } + } + } +} + +- (void)hideButtonsAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler +{ + if (self.isShowsPlusButton) + { + NSTimeInterval delay = 0.03; + + for (NSInteger i=1; i<_buttons.count; i++) + { + LGPlusButton *button = _buttons[i]; + + if (button.isShowing) + { + button.showing = NO; + + [self hideButtonAtIndex:i + animationType:_buttonsAppearingAnimationType + delay:delay*(i-1) + animated:animated + completionHandler:^(BOOL result) + { + if (completionHandler) completionHandler(); + }]; + } + } + } +} + +#pragma mark - Button Animations + +- (void)showButtonAtIndex:(NSUInteger)index + animationType:(LGPlusButtonsAppearingAnimationType)type + delay:(NSTimeInterval)delay + animated:(BOOL)animated + completionHandler:(void(^)(BOOL result))completionHandler +{ + WrapperView *buttonWrapperView1 = _buttonWrapperViews1[index]; + WrapperView *descriptionWrapperView = _descriptionWrapperViews[index]; + + // ----- + + CGAffineTransform transform = CGAffineTransformIdentity; + + if (type == LGPlusButtonsAppearingAnimationTypeCrossDissolveAndPop) + { + CGFloat scaleX = [[(CALayer *)buttonWrapperView1.layer.presentationLayer valueForKeyPath:@"transform.scale.x"] floatValue]; + CGFloat scaleY = [[(CALayer *)buttonWrapperView1.layer.presentationLayer valueForKeyPath:@"transform.scale.y"] floatValue]; + + if (scaleX && scaleY) + transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(scaleX, scaleY)); + } + else + { + transform = CGAffineTransformConcat(transform, CGAffineTransformMakeTranslation([[(CALayer *)buttonWrapperView1.layer.presentationLayer valueForKeyPath:@"transform.translation.x"] floatValue], + [[(CALayer *)buttonWrapperView1.layer.presentationLayer valueForKeyPath:@"transform.translation.y"] floatValue])); + } + + buttonWrapperView1.alpha = [(CALayer *)buttonWrapperView1.layer.presentationLayer opacity]; + buttonWrapperView1.transform = transform; + + descriptionWrapperView.alpha = buttonWrapperView1.alpha; + descriptionWrapperView.transform = buttonWrapperView1.transform; + + // ----- + + [buttonWrapperView1.layer removeAllAnimations]; + [descriptionWrapperView.layer removeAllAnimations]; + + // ----- + + if (!animated || type == LGPlusButtonsAppearingAnimationTypeNone) + { + [self showAnimationsWithButtonAtIndex:index]; + + if (completionHandler) completionHandler(YES); + } + else + { + CGFloat dif = 1.f-buttonWrapperView1.alpha; + + [LGPlusButtonsView animateStandartWithDuration:0.3*dif + delay:delay + animations:^(void) + { + [self showAnimationsWithButtonAtIndex:index]; + } + completion:^(BOOL finished) + { + if (completionHandler) completionHandler(finished); + }]; + } +} + +- (void)showAnimationsWithButtonAtIndex:(NSUInteger)index +{ + WrapperView *buttonWrapperView1 = _buttonWrapperViews1[index]; + WrapperView *descriptionWrapperView = _descriptionWrapperViews[index]; + + // ----- + + CGAffineTransform transform = CGAffineTransformIdentity; + + buttonWrapperView1.alpha = 1.f; + buttonWrapperView1.transform = transform; + + descriptionWrapperView.alpha = buttonWrapperView1.alpha; + descriptionWrapperView.transform = buttonWrapperView1.transform; +} + +- (void)hideButtonAtIndex:(NSUInteger)index + animationType:(LGPlusButtonsAppearingAnimationType)type + delay:(NSTimeInterval)delay + animated:(BOOL)animated + completionHandler:(void(^)(BOOL result))completionHandler +{ + WrapperView *buttonWrapperView1 = _buttonWrapperViews1[index]; + WrapperView *descriptionWrapperView = _descriptionWrapperViews[index]; + + // ----- + + CGAffineTransform transform = CGAffineTransformIdentity; + + if (type == LGPlusButtonsAppearingAnimationTypeCrossDissolveAndPop) + { + CGFloat scaleX = [[(CALayer *)buttonWrapperView1.layer.presentationLayer valueForKeyPath:@"transform.scale.x"] floatValue]; + CGFloat scaleY = [[(CALayer *)buttonWrapperView1.layer.presentationLayer valueForKeyPath:@"transform.scale.y"] floatValue]; + + if (scaleX && scaleY) + transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(scaleX, scaleY)); + } + else + { + transform = CGAffineTransformConcat(transform, CGAffineTransformMakeTranslation([[(CALayer *)buttonWrapperView1.layer.presentationLayer valueForKeyPath:@"transform.translation.x"] floatValue], + [[(CALayer *)buttonWrapperView1.layer.presentationLayer valueForKeyPath:@"transform.translation.y"] floatValue])); + } + + buttonWrapperView1.alpha = [(CALayer *)buttonWrapperView1.layer.presentationLayer opacity]; + buttonWrapperView1.transform = transform; + + descriptionWrapperView.alpha = buttonWrapperView1.alpha; + descriptionWrapperView.transform = buttonWrapperView1.transform; + + // ----- + + [buttonWrapperView1.layer removeAllAnimations]; + [descriptionWrapperView.layer removeAllAnimations]; + + // ----- + + if (type == LGPlusButtonsAppearingAnimationTypeNone) + { + [self hideAnimationsWithButtonAtIndex:index + animationType:type]; + + if (completionHandler) completionHandler(YES); + } + else + { + if (animated) + { + CGFloat dif = buttonWrapperView1.alpha-0.f; + + [UIView animateWithDuration:0.3*0.66*dif + delay:delay + options:0 + animations:^(void) + { + [self hideAnimationsWithButtonAtIndex:index + animationType:type]; + } + completion:^(BOOL finished) + { + if (completionHandler) completionHandler(finished); + }]; + } + else + { + [self hideAnimationsWithButtonAtIndex:index + animationType:type]; + + if (completionHandler) completionHandler(YES); + } + } +} + +- (void)hideAnimationsWithButtonAtIndex:(NSUInteger)index + animationType:(LGPlusButtonsAppearingAnimationType)type +{ + WrapperView *buttonWrapperView1 = _buttonWrapperViews1[index]; + WrapperView *descriptionWrapperView = _descriptionWrapperViews[index]; + + // ----- + + CGAffineTransform transform = CGAffineTransformIdentity; + + if (type == LGPlusButtonsAppearingAnimationTypeNone) + { + // + } + else if (type == LGPlusButtonsAppearingAnimationTypeCrossDissolve) + { + // + } + else if (type == LGPlusButtonsAppearingAnimationTypeCrossDissolveAndSlideHorizontal) + { + transform = CGAffineTransformConcat(transform, CGAffineTransformMakeTranslation(buttonWrapperView1.frame.size.width, 0.f)); + } + else if (type == LGPlusButtonsAppearingAnimationTypeCrossDissolveAndSlideVertical) + { + transform = CGAffineTransformConcat(transform, CGAffineTransformMakeTranslation(0.f, buttonWrapperView1.frame.size.height)); + } + else if (type == LGPlusButtonsAppearingAnimationTypeCrossDissolveAndPop) + { + transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(0.5, 0.5)); + } + + buttonWrapperView1.alpha = 0.f; + buttonWrapperView1.transform = transform; + + descriptionWrapperView.alpha = buttonWrapperView1.alpha; + descriptionWrapperView.transform = buttonWrapperView1.transform; +} + +#pragma mark - + +- (void)selectPlusButtonViewWithAnimationType:(LGPlusButtonAnimationType)type animated:(BOOL)animated completionHandler:(void(^)(BOOL result))completionHandler +{ + WrapperView *plusButtonWrapperView2 = _buttonWrapperViews2[0]; + + // ----- + + if (type == LGPlusButtonAnimationTypeCrossDissolve) + { + if (animated) + [UIView transitionWithView:plusButtonWrapperView2 + duration:0.2 + options:UIViewAnimationOptionTransitionCrossDissolve + animations:nil completion:completionHandler]; + } + else if (type == LGPlusButtonAnimationTypeRotate) + { + CGAffineTransform transform = CGAffineTransformIdentity; + transform = CGAffineTransformConcat(transform, CGAffineTransformMakeRotation(kLGPlusButtonsViewDegreesToRadians(45))); + + if (animated) + { + [UIView animateWithDuration:0.2 + animations:^(void) + { + plusButtonWrapperView2.transform = transform; + }]; + } + else + { + plusButtonWrapperView2.transform = transform; + + if (completionHandler) completionHandler(YES); + } + } +} + +- (void)deselectPlusButtonViewWithAnimationType:(LGPlusButtonAnimationType)type animated:(BOOL)animated completionHandler:(void(^)(BOOL result))completionHandler +{ + WrapperView *plusButtonWrapperView2 = _buttonWrapperViews2[0]; + + // ----- + + if (type == LGPlusButtonAnimationTypeCrossDissolve) + { + if (animated) + [UIView transitionWithView:plusButtonWrapperView2 + duration:0.2 + options:UIViewAnimationOptionTransitionCrossDissolve + animations:nil completion:completionHandler]; + } + else if (type == LGPlusButtonAnimationTypeRotate) + { + if (animated) + { + [UIView animateWithDuration:0.2 + animations:^(void) + { + plusButtonWrapperView2.transform = CGAffineTransformIdentity; + }]; + } + else + { + plusButtonWrapperView2.transform = CGAffineTransformIdentity; + + if (completionHandler) completionHandler(YES); + } + } +} + +#pragma mark - Observers + +- (void)addObservers +{ + if (!self.isObserversAdded && _parentView) + { + _observersAdded = YES; + + [_parentView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]; + + if ([_parentView isKindOfClass:[UIScrollView class]]) + { + [_parentView addObserver:self forKeyPath:@"contentInset" options:NSKeyValueObservingOptionNew context:nil]; + [_parentView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil]; + } + } +} + +- (void)removeObservers +{ + if (self.isObserversAdded && _parentView) + { + _observersAdded = NO; + + [_parentView removeObserver:self forKeyPath:@"frame"]; + + if ([_parentView isKindOfClass:[UIScrollView class]]) + { + [_parentView removeObserver:self forKeyPath:@"contentInset"]; + [_parentView removeObserver:self forKeyPath:@"contentOffset"]; + } + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if ([keyPath isEqualToString:@"frame"]) + [self layoutInvalidate]; + else if ([keyPath isEqualToString:@"contentInset"]) + [self layoutInvalidate]; + else if ([keyPath isEqualToString:@"contentOffset"]) + { + [self updatePosition]; + + if (self.isShowWhenScrolling) + { + UIScrollView *scrollView = (UIScrollView *)_parentView; + + CGPoint newOffset = [[change valueForKey:NSKeyValueChangeNewKey] CGPointValue]; + + CGFloat offsetY = newOffset.y; + CGFloat tempDiff = self.tempOffsetY - offsetY; + + if ((self.tempDiff > 0.f && tempDiff < 0.f) || (self.tempDiff < 0.f && tempDiff > 0.f) || self.tempDiff == 0.f) + { + self.offsetY = offsetY; + self.tempDiff = tempDiff; + } + else + { + CGFloat minDiff = 64.f; + CGFloat diff = self.offsetY - offsetY; + + if (scrollView.isTracking && scrollView.isDragging && (diff > minDiff || diff < -minDiff)) + { + if (self.offsetY > offsetY) + [self showAnimated:YES completionHandler:nil]; + else + [self hideAnimated:YES completionHandler:nil]; + } + } + + if (offsetY >= -scrollView.contentInset.top && + offsetY < scrollView.contentSize.height-scrollView.frame.size.height+scrollView.contentInset.bottom) + self.tempOffsetY = offsetY; + } + } + else + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; +} + +#pragma mark - Support + ++ (void)animateStandartWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay animations:(void(^)())animations completion:(void(^)(BOOL finished))completion +{ + if ([UIDevice currentDevice].systemVersion.floatValue >= 7.0) + { + [UIView animateWithDuration:duration + delay:delay + usingSpringWithDamping:1.f + initialSpringVelocity:0.5 + options:0 + animations:animations + completion:completion]; + } + else + { + [UIView animateWithDuration:duration*0.66 + delay:delay + options:UIViewAnimationOptionCurveEaseInOut + animations:animations + completion:completion]; + } +} + +@end diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..676f292 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Grigory Lutkov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..10a07d5 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +# LGPlusButtonsView + +iOS implementation of Google 'plus button', that shows more options. + +## Preview + + + + + + +## Installation + +### With source code + +[Download repository](https://github.com/Friend-LGA/LGPlusButtonsView/archive/master.zip), then add [LGPlusButtonsView directory](https://github.com/Friend-LGA/LGPlusButtonsView/blob/master/LGPlusButtonsView/) to your project. + +### With CocoaPods + +[CocoaPods](http://cocoapods.org/) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries in your projects. See the "Get Started" section for more details. + +#### Podfile + +``` +platform :ios, '6.0' +pod 'LGPlusButtonsView', '~> 1.0.0' +``` + +## Usage + +In the source files where you need to use the library, import the header file: + +```objective-c +#import "LGPlusButtonsView.h" +``` + +### Initialization + +You have several methods for initialization: + +```objective-c +- (instancetype)initWithView:(UIView *)view + numberOfButtons:(NSUInteger)numberOfButtons + showsPlusButton:(BOOL)showsPlusButton; +``` + +More init methods you can find in [LGPlusButtonsView.h](https://github.com/Friend-LGA/LGPlusButtonsView/blob/master/LGPlusButtonsView/LGPlusButtonsView.h) + +### Handle actions + +To handle actions you can use initialization methods with blocks or delegate, or implement it after initialization. + +#### Delegate + +```objective-c +@property (assign, nonatomic) id delegate; + +- (void)plusButtonsView:(LGPlusButtonsView *)plusButtonsView buttonPressedWithTitle:(NSString *)title description:(NSString *)description index:(NSUInteger)index; +- (void)plusButtonsViewPlusButtonPressed:(LGPlusButtonsView *)plusButtonsView; +``` + +#### Blocks + +```objective-c +@property (strong, nonatomic) void (^actionHandler)(LGPlusButtonsView *plusButtonView, NSString *title, NSString *description, NSUInteger index); +@property (strong, nonatomic) void (^plusButtonActionHandler)(LGPlusButtonsView *plusButtonView); +``` + +### More + +For more details try Xcode [Demo project](https://github.com/Friend-LGA/LGPlusButtonsView/blob/master/Demo) and see [LGPlusButtonsView.h](https://github.com/Friend-LGA/LGPlusButtonsView/blob/master/LGPlusButtonsView/LGPlusButtonsView.h) + +## License + +LGPlusButtonsView is released under the MIT license. See [LICENSE](https://raw.githubusercontent.com/Friend-LGA/LGPlusButtonsView/master/LICENSE) for details.