Compare commits

...

33 Commits

Author SHA1 Message Date
igork-ramotion 4534c0dcd4 Merge pull request #64 from nzufelt/patch-1
Fix typo!
2020-04-09 13:59:56 +03:00
Nicholas Zufelt b24752e27a Fix typo! 2020-04-08 16:30:13 -04:00
Ramotion 22ef289da4 Update README.md 2020-04-06 09:54:27 +03:00
igor.k 1428534fcc fix problems with running on simulator (issue #61) 2019-11-13 00:45:34 +03:00
igor.k 3ee0a8a606 add SPM config and Ramotion application icon set 2019-11-13 00:34:54 +03:00
Ramotion 0f35c65a48 Update README.md 2019-10-12 21:11:13 +03:00
Alex K c578516270 bump version 2019-04-03 15:41:12 +03:00
Alex K 1d00b258e9 converted to swift 5 2019-04-03 15:38:21 +03:00
Ramotion 37940a69eb Update README.md 2018-12-28 12:52:30 +03:00
Ramotion 739c698c02 Add files via upload 2018-12-28 01:44:28 -08:00
Ramotion 3289f9c315 Update README.md 2018-12-10 11:31:41 +03:00
Ramotion 82f01134d2 Update README.md 2018-12-10 10:21:29 +03:00
Alex K f6d7e82c98 update podspec 2018-10-13 11:24:54 +03:00
Alex 5c8a416f5b Merge pull request #57 from tache/master
added circle open delegate
2018-10-13 11:20:36 +03:00
tache 0122f09e6b Merged with upstream 2018-10-13 00:34:14 -04:00
Alex K 98a4fa1db9 swift 4.2 2018-09-27 09:09:58 +03:00
tache a766ceddbd Updated to Swift 4.2 2018-09-24 14:15:00 -04:00
Alex K 6d961f5923 update podspec 2018-07-02 10:04:48 +03:00
tache 3968b56d02 Update to Swift 4 2017-11-03 20:34:04 -04:00
tache fc589564b4 no message 2017-11-03 20:19:42 -04:00
tache 41df3a1714 Merge remote-tracking branch 'upstream/master' 2017-09-28 10:22:59 -04:00
tache 5782a0fafa Merge branch 'master' of github.com:tache/circle-menu
* 'master' of github.com:tache/circle-menu:
  Updated to Swift 3.2
  Updated for 8.3 and optional callbacks
  updating readme document
  Added in an open menu and made open/close delegates fire asynchronously
  Moved the collapse to the proper location - should only fire once
2017-04-03 19:19:11 -04:00
tache 0652edf64d Updated to Swift 3.2 2017-04-03 19:18:48 -04:00
tache 1fffcfb25e Updated for 8.3 and optional callbacks 2017-04-03 19:18:48 -04:00
tache 3f3a676a6d updating readme document 2017-04-03 19:18:48 -04:00
tache 7a6175e8fb Added in an open menu and made open/close delegates fire asynchronously 2017-04-03 19:18:48 -04:00
tache 6cf24b1ee1 Moved the collapse to the proper location - should only fire once 2017-04-03 19:18:48 -04:00
tache c37e32ce3f Updated to Swift 3.2 2017-04-03 19:13:50 -04:00
tache 38926b111a Updated for 8.3 and optional callbacks 2017-04-03 19:09:48 -04:00
tache dce71006c9 updating readme document 2017-01-15 10:53:52 -05:00
tache 77ae3b58c9 Added in an open menu and made open/close delegates fire asynchronously 2017-01-15 10:30:19 -05:00
Chris Graham 2d23e4f7f3 Merge pull request #1 from tache/fix-collapse-delegate
Moved the collapse to the proper location - should only fire once
2017-01-15 08:46:16 -05:00
tache 7e95b925a5 Moved the collapse to the proper location - should only fire once 2017-01-15 08:39:22 -05:00
28 changed files with 291 additions and 132 deletions
+1 -1
View File
@@ -1 +1 @@
4.0
4.2
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'CircleMenu'
s.version = '3.0.6'
s.version = '4.1.0'
s.summary = 'Amazing animation with buttons'
s.homepage = 'https://github.com/Ramotion/circle-menu'
s.license = 'MIT'
+53 -27
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 51;
objects = {
/* Begin PBXBuildFile section */
@@ -17,7 +17,6 @@
841EC5911C58E898008872D5 /* CircleMenuButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841EC58F1C58E898008872D5 /* CircleMenuButton.swift */; };
841EC5941C58F3E2008872D5 /* CircleMenuLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841EC5931C58F3E2008872D5 /* CircleMenuLoader.swift */; };
8497460C1C6A1C5D001E7184 /* CircleMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841EC58D1C58E898008872D5 /* CircleMenu.swift */; };
8497460D1C6A1C6D001E7184 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84F248BD1C58E65F008F12C1 /* Assets.xcassets */; };
8497460E1C6A1C9D001E7184 /* CircleMenuLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841EC5931C58F3E2008872D5 /* CircleMenuLoader.swift */; };
8497460F1C6A1CA0001E7184 /* CircleMenuButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841EC58F1C58E898008872D5 /* CircleMenuButton.swift */; };
84F248B71C58E65F008F12C1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F248B61C58E65F008F12C1 /* AppDelegate.swift */; };
@@ -72,7 +71,6 @@
84F248BB1C58E65F008F12C1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
84F248BD1C58E65F008F12C1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
84F248C01C58E65F008F12C1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
84F248C21C58E65F008F12C1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
84F248C71C58E65F008F12C1 /* CircleMenuTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CircleMenuTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
84F248CB1C58E65F008F12C1 /* CircleMenuTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleMenuTests.swift; sourceTree = "<group>"; };
84F248CD1C58E65F008F12C1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -168,7 +166,6 @@
84F248BA1C58E65F008F12C1 /* Main.storyboard */,
84F248BD1C58E65F008F12C1 /* Assets.xcassets */,
84F248BF1C58E65F008F12C1 /* LaunchScreen.storyboard */,
84F248C21C58E65F008F12C1 /* Info.plist */,
);
path = CircleMenu;
sourceTree = "<group>";
@@ -258,27 +255,28 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0920;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "Alex K.";
TargetAttributes = {
8403F5781CFF2C2E007D0BD1 = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0900;
LastSwiftMigration = 1020;
};
84F248B21C58E65F008F12C1 = {
CreatedOnToolsVersion = 7.2;
DevelopmentTeam = 34MUF9YXTA;
LastSwiftMigration = 0900;
LastSwiftMigration = 1020;
};
84F248C61C58E65F008F12C1 = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 1020;
TestTargetID = 84F248B21C58E65F008F12C1;
};
};
};
buildConfigurationList = 84F248AE1C58E65F008F12C1 /* Build configuration list for PBXProject "CircleMenu" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
compatibilityVersion = "Xcode 10.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -318,7 +316,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8497460D1C6A1C6D001E7184 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -406,12 +403,15 @@
INFOPLIST_FILE = CircleMenu/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.CircleMenu;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@@ -431,12 +431,15 @@
INFOPLIST_FILE = CircleMenu/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.CircleMenu;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@@ -447,6 +450,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -455,12 +459,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -492,7 +498,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -500,6 +506,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -508,12 +515,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -537,8 +546,9 @@
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 4.2;
VALIDATE_PRODUCT = YES;
};
name = Release;
@@ -549,14 +559,17 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
CURRENT_PROJECT_VERSION = 1;
INFOPLIST_FILE = CircleMenu/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
OTHER_SWIFT_FLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.dev;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -566,14 +579,17 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
CURRENT_PROJECT_VERSION = 1;
INFOPLIST_FILE = CircleMenu/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
OTHER_SWIFT_FLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.dev;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
};
name = Release;
};
@@ -582,9 +598,14 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
INFOPLIST_FILE = CircleMenuTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.CircleMenuTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CircleMenuDemo.app/CircleMenuDemo";
};
name = Debug;
@@ -594,9 +615,14 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
INFOPLIST_FILE = CircleMenuTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.CircleMenuTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CircleMenuDemo.app/CircleMenuDemo";
};
name = Release;
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0920"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,7 +26,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -37,7 +36,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
+1 -1
View File
@@ -15,7 +15,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_: UIApplication,
didFinishLaunchingWithOptions _: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
}
+75 -9
View File
@@ -1,53 +1,119 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"idiom" : "iphone",
"filename" : "icon-40.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"idiom" : "iphone",
"filename" : "icon-60.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"idiom" : "iphone",
"filename" : "icon-58.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"idiom" : "iphone",
"filename" : "icon-87.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"idiom" : "iphone",
"filename" : "icon-80.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"idiom" : "iphone",
"filename" : "icon-120.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"idiom" : "iphone",
"filename" : "icon-120.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"idiom" : "iphone",
"filename" : "icon-180.png",
"scale" : "3x"
},
{
"idiom" : "ios-marketing",
"size" : "20x20",
"idiom" : "ipad",
"filename" : "icon-20.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "icon-40.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "icon-29.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "icon-58.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "icon-40.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "icon-80.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "icon-76.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "icon-152.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "icon-167.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Ramotion1024.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"pre-rendered" : true
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

+1 -1
View File
@@ -26,7 +26,7 @@ class ViewController: UIViewController, CircleMenuDelegate {
("icon_search", UIColor(red: 0.22, green: 0.74, blue: 0, alpha: 1)),
("notifications-btn", UIColor(red: 0.96, green: 0.23, blue: 0.21, alpha: 1)),
("settings-btn", UIColor(red: 0.51, green: 0.15, blue: 1, alpha: 1)),
("nearby-btn", UIColor(red: 1, green: 0.39, blue: 0, alpha: 1)),
("nearby-btn", UIColor(red: 1, green: 0.39, blue: 0, alpha: 1))
]
override func viewDidLoad() {
super.viewDidLoad()
+47 -36
View File
@@ -66,11 +66,18 @@ func customize<Type>(_ value: Type, block: (_ object: Type) -> Void) -> Type {
@objc optional func circleMenu(_ circleMenu: CircleMenu, buttonDidSelected button: UIButton, atIndex: Int)
/**
Tells the delegate that the menu was collapsed - the cancel action.
Tells the delegate that the menu was collapsed - the cancel action. Fires immediately on button press
- parameter circleMenu: A circle menu object informing the delegate about the new index selection.
*/
@objc optional func menuCollapsed(_ circleMenu: CircleMenu)
/**
Tells the delegate that the menu was opened. Fires immediately on button press
- parameter circleMenu: A circle menu object informing the delegate about the new index selection.
*/
@objc optional func menuOpened(_ circleMenu: CircleMenu)
}
// MARK: CircleMenu
@@ -95,9 +102,9 @@ open class CircleMenu: UIButton {
// Pop buttons radius, if nil use center button size
open var subButtonsRadius: CGFloat?
// Show buttons event
open var showButtonsEvent: UIControlEvents = UIControlEvents.touchUpInside {
open var showButtonsEvent: UIControl.Event = UIControl.Event.touchUpInside {
didSet {
addActions(newEvent: showButtonsEvent, oldEvent: oldValue)
}
@@ -160,7 +167,7 @@ open class CircleMenu: UIButton {
customSelectedIconView = addCustomImageView(state: .selected)
customSelectedIconView?.alpha = 0
setImage(UIImage(), for: .normal)
setImage(UIImage(), for: .selected)
}
@@ -198,13 +205,14 @@ open class CircleMenu: UIButton {
}
}
return true
}
open override func removeFromSuperview() {
if self.platform?.superview != nil { self.platform?.removeFromSuperview() }
super.removeFromSuperview()
}
open override func removeFromSuperview() {
if self.platform?.superview != nil { self.platform?.removeFromSuperview() }
super.removeFromSuperview()
}
// MARK: create
fileprivate func createButtons(platform: UIView) -> [UIButton] {
@@ -223,7 +231,7 @@ open class CircleMenu: UIButton {
}
let button = customize(CircleMenuButton(size: buttonSize, platform: platform, distance: distance, angle: angle)) {
$0.tag = index
$0.addTarget(self, action: #selector(CircleMenu.buttonHandler(_:)), for: UIControlEvents.touchUpInside)
$0.addTarget(self, action: #selector(CircleMenu.buttonHandler(_:)), for: UIControl.Event.touchUpInside)
$0.alpha = 0
}
buttons.append(button)
@@ -231,7 +239,7 @@ open class CircleMenu: UIButton {
return buttons
}
fileprivate func addCustomImageView(state: UIControlState) -> UIImageView? {
fileprivate func addCustomImageView(state: UIControl.State) -> UIImageView? {
guard let image = image(for: state) else {
return nil
}
@@ -267,7 +275,7 @@ open class CircleMenu: UIButton {
superview?.insertSubview(platform, belowSubview: self)
// constraints
let sizeConstraints = [NSLayoutAttribute.width, .height].map {
let sizeConstraints = [NSLayoutConstraint.Attribute.width, .height].map {
NSLayoutConstraint(item: platform,
attribute: $0,
relatedBy: .equal,
@@ -278,7 +286,7 @@ open class CircleMenu: UIButton {
}
platform.addConstraints(sizeConstraints)
let centerConstraints = [NSLayoutAttribute.centerX, .centerY].map {
let centerConstraints = [NSLayoutConstraint.Attribute.centerX, .centerY].map {
NSLayoutConstraint(item: self,
attribute: $0,
relatedBy: .equal,
@@ -294,7 +302,7 @@ open class CircleMenu: UIButton {
// MARK: configure
fileprivate func addActions(newEvent: UIControlEvents, oldEvent: UIControlEvents? = nil) {
fileprivate func addActions(newEvent: UIControl.Event, oldEvent: UIControl.Event? = nil) {
if let oldEvent = oldEvent { removeTarget(self, action: #selector(CircleMenu.onTap), for: oldEvent) }
addTarget(self, action: #selector(CircleMenu.onTap), for: newEvent)
}
@@ -318,7 +326,7 @@ open class CircleMenu: UIButton {
}
// MARK: actions
private var isBounceAnimating: Bool = false
@objc func onTap() {
@@ -329,6 +337,9 @@ open class CircleMenu: UIButton {
let platform = createPlatform()
buttons = createButtons(platform: platform)
self.platform = platform
DispatchQueue.main.asyncAfter(deadline: .now()) {
self.delegate?.menuOpened?(self)
}
}
let isShow = !buttonsIsShown()
let duration = isShow ? 0.5 : 0.2
@@ -345,7 +356,7 @@ open class CircleMenu: UIButton {
let strokeWidth: CGFloat
if let radius = self.subButtonsRadius {
strokeWidth = radius * 2
strokeWidth = radius * 2
} else {
strokeWidth = bounds.size.height
}
@@ -357,7 +368,7 @@ open class CircleMenu: UIButton {
if let container = sender.container { // rotation animation
sender.rotationAnimation(container.angleZ + 360, duration: duration)
container.superview?.bringSubview(toFront: container)
container.superview?.bringSubviewToFront(container)
}
let step = getArcStep()
@@ -367,14 +378,14 @@ open class CircleMenu: UIButton {
circle.hideAnimation(0.5, delay: duration) { [weak self] in
if self?.platform?.superview != nil { self?.platform?.removeFromSuperview() }
}
hideCenterButton(duration: 0.3)
showCenterButton(duration: 0.525, delay: duration)
DispatchQueue.main.asyncAfter(deadline: .now() + duration, execute: {
self.delegate?.circleMenu?(self, buttonDidSelected: sender, atIndex: sender.tag)
})
}
}
// MARK: animations
@@ -407,10 +418,10 @@ open class CircleMenu: UIButton {
fileprivate func tapBounceAnimation(duration: TimeInterval, completion: ((Bool)->())? = nil) {
transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 5,
options: UIViewAnimationOptions.curveLinear,
options: UIView.AnimationOptions.curveLinear,
animations: { () -> Void in
self.transform = CGAffineTransform(scaleX: 1, y: 1)
},
self.transform = CGAffineTransform(scaleX: 1, y: 1)
},
completion: completion)
}
@@ -436,21 +447,21 @@ open class CircleMenu: UIButton {
$0.duration = TimeInterval(duration)
$0.toValue = (toAngle.degrees)
$0.fromValue = (fromAngle.degrees)
$0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
$0.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
}
let fade = customize(CABasicAnimation(keyPath: "opacity")) {
$0.duration = TimeInterval(duration)
$0.fromValue = fromOpacity
$0.toValue = toOpacity
$0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
$0.fillMode = kCAFillModeForwards
$0.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
$0.fillMode = CAMediaTimingFillMode.forwards
$0.isRemovedOnCompletion = false
}
let scale = customize(CABasicAnimation(keyPath: "transform.scale")) {
$0.duration = TimeInterval(duration)
$0.toValue = toScale
$0.fromValue = fromScale
$0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
$0.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
}
view.layer.add(rotation, forKey: nil)
@@ -471,19 +482,19 @@ open class CircleMenu: UIButton {
fileprivate func hideCenterButton(duration: Double, delay: Double = 0) {
UIView.animate(withDuration: TimeInterval(duration), delay: TimeInterval(delay),
options: UIViewAnimationOptions.curveEaseOut,
options: UIView.AnimationOptions.curveEaseOut,
animations: { () -> Void in
self.transform = CGAffineTransform(scaleX: 0.001, y: 0.001)
self.transform = CGAffineTransform(scaleX: 0.001, y: 0.001)
}, completion: nil)
}
fileprivate func showCenterButton(duration: Float, delay: Double) {
UIView.animate(withDuration: TimeInterval(duration), delay: TimeInterval(delay), usingSpringWithDamping: 0.78,
initialSpringVelocity: 0, options: UIViewAnimationOptions.curveLinear,
initialSpringVelocity: 0, options: UIView.AnimationOptions.curveLinear,
animations: { () -> Void in
self.transform = CGAffineTransform(scaleX: 1, y: 1)
self.alpha = 1
},
self.transform = CGAffineTransform(scaleX: 1, y: 1)
self.alpha = 1
},
completion: nil)
let rotation = customize(CASpringAnimation(keyPath: "transform.rotation")) {
@@ -498,16 +509,16 @@ open class CircleMenu: UIButton {
let fade = customize(CABasicAnimation(keyPath: "opacity")) {
$0.duration = TimeInterval(0.01)
$0.toValue = 0
$0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
$0.fillMode = kCAFillModeForwards
$0.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
$0.fillMode = CAMediaTimingFillMode.forwards
$0.isRemovedOnCompletion = false
$0.beginTime = CACurrentMediaTime() + delay
}
let show = customize(CABasicAnimation(keyPath: "opacity")) {
$0.duration = TimeInterval(duration)
$0.toValue = 1
$0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
$0.fillMode = kCAFillModeForwards
$0.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
$0.fillMode = CAMediaTimingFillMode.forwards
$0.isRemovedOnCompletion = false
$0.beginTime = CACurrentMediaTime() + delay
}
@@ -117,7 +117,7 @@ internal class CircleMenuButton: UIButton {
UIView.animate(
withDuration: duration,
delay: delay,
options: UIViewAnimationOptions(),
options: UIView.AnimationOptions(),
animations: { () -> Void in
container.layer.transform = rotateTransform
},
@@ -132,7 +132,7 @@ internal class CircleMenuButton: UIButton {
internal extension CircleMenuButton {
internal func showAnimation(distance: Float, duration: Double, delay: Double = 0) {
func showAnimation(distance: Float, duration: Double, delay: Double = 0) {
guard let heightConstraint = (self.container?.constraints.filter { $0.identifier == "height" })?.first else {
fatalError()
}
@@ -148,7 +148,7 @@ internal extension CircleMenuButton {
delay: delay,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0,
options: UIViewAnimationOptions.curveLinear,
options: UIView.AnimationOptions.curveLinear,
animations: { () -> Void in
self.container?.superview?.layoutIfNeeded()
self.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
@@ -157,7 +157,7 @@ internal extension CircleMenuButton {
})
}
internal func hideAnimation(distance: Float, duration: Double, delay: Double = 0) {
func hideAnimation(distance: Float, duration: Double, delay: Double = 0) {
guard let heightConstraint = (self.container?.constraints.filter { $0.identifier == "height" })?.first else {
return
}
@@ -166,7 +166,7 @@ internal extension CircleMenuButton {
UIView.animate(
withDuration: duration,
delay: delay,
options: UIViewAnimationOptions.curveEaseIn,
options: UIView.AnimationOptions.curveEaseIn,
animations: { () -> Void in
self.container?.superview?.layoutIfNeeded()
self.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
@@ -179,7 +179,7 @@ internal extension CircleMenuButton {
})
}
internal func changeDistance(_ distance: CGFloat, animated _: Bool, duration: Double = 0, delay: Double = 0) {
func changeDistance(_ distance: CGFloat, animated _: Bool, duration: Double = 0, delay: Double = 0) {
guard let heightConstraint = (self.container?.constraints.filter { $0.identifier == "height" })?.first else {
fatalError()
@@ -190,7 +190,7 @@ internal extension CircleMenuButton {
UIView.animate(
withDuration: duration,
delay: delay,
options: UIViewAnimationOptions.curveEaseIn,
options: UIView.AnimationOptions.curveEaseIn,
animations: { () -> Void in
self.container?.superview?.layoutIfNeeded()
},
@@ -199,11 +199,11 @@ internal extension CircleMenuButton {
// MARK: layer animation
internal func rotationAnimation(_ angle: Float, duration: Double) {
func rotationAnimation(_ angle: Float, duration: Double) {
let rotation = customize(CABasicAnimation(keyPath: "transform.rotation")) {
$0.duration = TimeInterval(duration)
$0.toValue = (angle.degrees)
$0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
$0.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
}
container?.layer.add(rotation, forKey: "rotation")
}
@@ -81,7 +81,7 @@ internal class CircleMenuLoader: UIView {
translatesAutoresizingMaskIntoConstraints = false
// added constraints
let sizeConstraints = [NSLayoutAttribute.width, .height].map {
let sizeConstraints = [NSLayoutConstraint.Attribute.width, .height].map {
NSLayoutConstraint(item: self,
attribute: $0,
relatedBy: .equal,
@@ -92,7 +92,7 @@ internal class CircleMenuLoader: UIView {
}
addConstraints(sizeConstraints)
let centerConstaraints = [NSLayoutAttribute.centerY, .centerX].map {
let centerConstaraints = [NSLayoutConstraint.Attribute.centerY, .centerX].map {
NSLayoutConstraint(item: platform,
attribute: $0,
relatedBy: .equal,
@@ -129,7 +129,7 @@ internal class CircleMenuLoader: UIView {
$0.duration = CFTimeInterval(duration)
$0.fromValue = 0
$0.toValue = 1
$0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
$0.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
}
circle?.add(animation, forKey: nil)
CATransaction.commit()
@@ -140,9 +140,9 @@ internal class CircleMenuLoader: UIView {
let scale = customize(CABasicAnimation(keyPath: "transform.scale")) {
$0.toValue = 1.2
$0.duration = CFTimeInterval(duration)
$0.fillMode = kCAFillModeForwards
$0.fillMode = CAMediaTimingFillMode.forwards
$0.isRemovedOnCompletion = false
$0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
$0.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
$0.beginTime = CACurrentMediaTime() + delay
}
layer.add(scale, forKey: nil)
@@ -150,7 +150,7 @@ internal class CircleMenuLoader: UIView {
UIView.animate(
withDuration: CFTimeInterval(duration),
delay: delay,
options: UIViewAnimationOptions.curveEaseIn,
options: UIView.AnimationOptions.curveEaseIn,
animations: { () -> Void in
self.alpha = 0
},
+1 -1
View File
@@ -60,7 +60,7 @@ class CircleMenuTests: XCTestCase {
circleMenu.onTap()
// when
circleMenu.buttonHandler((circleMenu.buttons?.first)!)
circleMenu.buttonHandler((circleMenu.buttons?.first)! as! CircleMenuButton)
// then
XCTAssertNil(circleMenu.buttons, "button is removed")
+42
View File
@@ -0,0 +1,42 @@
// swift-tools-version:5.1
//
// Package.swift
//
// Copyright (c) Ramotion (https://www.ramotion.com/)
//
// 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 PackageDescription
let package = Package(
name: "CircleMenu",
platforms: [
.iOS(.v9)
],
products: [
.library(name: "CircleMenu",
targets: ["CircleMenu"])
],
targets: [
.target(name: "CircleMenu",
path: "CircleMenuLib")
],
swiftLanguageVersions: [.v5]
)
+45 -37
View File
@@ -1,8 +1,27 @@
![header](./header.png)
<img src="https://github.com/Ramotion/circle-menu/blob/master/circle-menu.gif" width="600" height="450" />
<br><br/>
<a href="https://www.ramotion.com/agency/app-development/?utm_source=gthb&utm_medium=repo&utm_campaign=circle-menu"><img src="https://github.com/Ramotion/circle-menu/blob/master/header.png"></a>
<a href="https://github.com/Ramotion/circle-menu">
<img align="left" src="https://github.com/Ramotion/circle-menu/blob/master/circle-menu.gif" width="480" height="360" /></a>
<p><h1 align="left">CIRCLE MENU</h1></p>
<h4>Simple, elegant UI menu with a circular layout and material design animations</h4>
___
<p><h6>We specialize in the designing and coding of custom UI for Mobile Apps and Websites.</h6>
<a href="https://www.ramotion.com/agency/app-development/?utm_source=gthb&utm_medium=repo&utm_campaign=circle-menu">
<img src="https://github.com/ramotion/gliding-collection/raw/master/contact_our_team@2x.png" width="187" height="34"></a>
</p>
<p><h6>Stay tuned for the latest updates:</h6>
<a href="https://goo.gl/rPFpid" >
<img src="https://i.imgur.com/ziSqeSo.png/" width="156" height="28"></a></p>
</br>
# CircleMenu
[![Twitter](https://img.shields.io/badge/Twitter-@Ramotion-blue.svg?style=flat)](http://twitter.com/Ramotion)
[![CocoaPods](https://img.shields.io/cocoapods/p/CircleMenu.svg)](https://cocoapods.org/pods/CircleMenu)
[![CocoaPods](https://img.shields.io/cocoapods/v/CircleMenu.svg)](http://cocoapods.org/pods/CircleMenu)
@@ -12,24 +31,6 @@
[![Travis](https://img.shields.io/travis/Ramotion/circle-menu.svg)](https://travis-ci.org/Ramotion/circle-menu)
[![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://paypal.me/Ramotion)
# Check this library on other platforms:
<a href="https://github.com/Ramotion/circle-menu-android">
<img src="https://github.com/ramotion/navigation-stack/raw/master/Android_Java@2x.png" width="178" height="81"></a>
<a href="https://github.com/Ramotion/react-native-circle-menu">
<img src="https://github.com/ramotion/navigation-stack/raw/master/React Native@2x.png" width="178" height="81"></a>
**Looking for developers for your project?**<br>
This project is maintained by Ramotion, Inc. We specialize in the designing and coding of custom UI for Mobile Apps and Websites.
<a href="mailto:alex.a@ramotion.com?subject=Project%20inquiry%20from%20Github">
<img src="https://github.com/ramotion/gliding-collection/raw/master/contact_our_team@2x.png" width="187" height="34"></a> <br>
The [iPhone mockup](https://store.ramotion.com/product/iphone-x-clay-mockups?utm_source=gthb&utm_medium=special&utm_campaign=circle-menu) available [here](https://store.ramotion.com?utm_source=gthb&utm_medium=special&utm_campaign=circle-menu).
## Try this UI control in action
<a href="https://itunes.apple.com/app/apple-store/id1182360240?pt=550053&ct=gthb-circle-menu&mt=8" > <img src="https://github.com/Ramotion/navigation-stack/raw/master/Download_on_the_App_Store_Badge_US-UK_135x40.png" width="170" height="58"></a>
## Requirements
@@ -64,7 +65,7 @@ github "Ramotion/circle-menu"
func circleMenu(circleMenu: CircleMenu, willDisplay button: UIButton, atIndex: Int)
```
4) Use properties to confiure CircleMenu
4) Use properties to configure CircleMenu
```swift
@IBInspectable var buttonsCount: Int = 3
@@ -99,29 +100,36 @@ optional func circleMenu(circleMenu: CircleMenu, buttonWillSelected button: UIBu
// call after animation
optional func circleMenu(circleMenu: CircleMenu, buttonDidSelected button: UIButton, atIndex: Int)
// call upon cancel of the menu
// call upon cancel of the menu - fires immediately on button press
optional func menuCollapsed(circleMenu: CircleMenu)
// call upon opening of the menu - fires immediately on button press
optional func menuOpened(circleMenu: CircleMenu)
```
## 🗂 Check this library on other language:
<a href="https://github.com/Ramotion/circle-menu-android">
<img src="https://github.com/ramotion/navigation-stack/raw/master/Android_Java@2x.png" width="178" height="81"></a>
<a href="https://github.com/Ramotion/react-native-circle-menu">
<img src="https://github.com/ramotion/navigation-stack/raw/master/React Native@2x.png" width="178" height="81"></a>
## 📄 License
Circle Menu is released under the MIT license.
See [LICENSE](./LICENSE) for details.
This library is a part of a <a href="https://github.com/Ramotion/swift-ui-animation-components-and-libraries"><b>selection of our best UI open-source projects.</b></a>
## Licence
If you use the open-source library in your project, please make sure to credit and backlink to www.ramotion.com
Circle menu is released under the MIT license.
See [LICENSE](./LICENSE) for details.
<br>
## 📱 Get the Showroom App for iOS to give it a try
Try this UI component and more like this in our iOS app. Contact us if interested.
# Get the Showroom App for iOS and Android to give it a try
Try this UI component and more like this in our mobile app. Contact us if interested.
<a href="https://itunes.apple.com/app/apple-store/id1182360240?pt=550053&ct=circle-menu&mt=8" >
<a href="https://itunes.apple.com/app/apple-store/id1182360240?pt=550053&ct=folding-cell&mt=8" >
<img src="https://github.com/ramotion/gliding-collection/raw/master/app_store@2x.png" width="117" height="34"></a>
<a href="mailto:alex.a@ramotion.com?subject=Project%20inquiry%20from%20Github">
<a href="https://www.ramotion.com/agency/app-development/?utm_source=gthb&utm_medium=repo&utm_campaign=circle-menu">
<img src="https://github.com/ramotion/gliding-collection/raw/master/contact_our_team@2x.png" width="187" height="34"></a>
<br>
<br>
Follow us for the latest updates<br>
<a href="https://goo.gl/rPFpid" >
<img src="https://i.imgur.com/ziSqeSo.png/" width="156" height="28"></a>
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 16 KiB