From 00986aca7d3af80da739f2d968dfffeb7a968737 Mon Sep 17 00:00:00 2001 From: tsuzukihashi Date: Wed, 11 Mar 2020 05:47:41 +0900 Subject: [PATCH] Custom NeumorphismButton --- DemoApp/DemoApp.xcodeproj/project.pbxproj | 4 --- DemoApp/DemoApp/ContentView.swift | 4 +-- .../NeumorphismRoundedRectangleButton.swift | 35 ------------------- NeumorphismUI.xcodeproj/project.pbxproj | 8 +++++ Sources/AnyShape.swift | 17 +++++++++ Sources/CustomViews/NeumorphismButton.swift | 28 ++++++++++++--- Sources/Extensions/ViewExtension.swift | 4 +-- Sources/ShapeType.swift | 9 +++++ 8 files changed, 62 insertions(+), 47 deletions(-) delete mode 100644 DemoApp/DemoApp/NeumorphismRoundedRectangleButton.swift create mode 100644 Sources/AnyShape.swift create mode 100644 Sources/ShapeType.swift diff --git a/DemoApp/DemoApp.xcodeproj/project.pbxproj b/DemoApp/DemoApp.xcodeproj/project.pbxproj index 824832d..d9a51be 100644 --- a/DemoApp/DemoApp.xcodeproj/project.pbxproj +++ b/DemoApp/DemoApp.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ DA1A6B74240B81A6001EA5EB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA1A6B73240B81A6001EA5EB /* Assets.xcassets */; }; DA1A6B77240B81A6001EA5EB /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA1A6B76240B81A6001EA5EB /* Preview Assets.xcassets */; }; DA1A6B7A240B81A6001EA5EB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DA1A6B78240B81A6001EA5EB /* LaunchScreen.storyboard */; }; - DA5AFAC7241517190098E0BB /* NeumorphismRoundedRectangleButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5AFAC6241517190098E0BB /* NeumorphismRoundedRectangleButton.swift */; }; DA74B267240B820400AD9A06 /* NeumorphismUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA74B266240B820400AD9A06 /* NeumorphismUI.framework */; }; DA74B268240B820400AD9A06 /* NeumorphismUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DA74B266240B820400AD9A06 /* NeumorphismUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ @@ -41,7 +40,6 @@ DA1A6B76240B81A6001EA5EB /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; DA1A6B79240B81A6001EA5EB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; DA1A6B7B240B81A6001EA5EB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - DA5AFAC6241517190098E0BB /* NeumorphismRoundedRectangleButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphismRoundedRectangleButton.swift; sourceTree = ""; }; DA74B266240B820400AD9A06 /* NeumorphismUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = NeumorphismUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -80,7 +78,6 @@ DA1A6B6D240B81A4001EA5EB /* AppDelegate.swift */, DA1A6B6F240B81A4001EA5EB /* SceneDelegate.swift */, DA1A6B71240B81A4001EA5EB /* ContentView.swift */, - DA5AFAC6241517190098E0BB /* NeumorphismRoundedRectangleButton.swift */, DA1A6B73240B81A6001EA5EB /* Assets.xcassets */, DA1A6B78240B81A6001EA5EB /* LaunchScreen.storyboard */, DA1A6B7B240B81A6001EA5EB /* Info.plist */, @@ -177,7 +174,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DA5AFAC7241517190098E0BB /* NeumorphismRoundedRectangleButton.swift in Sources */, DA1A6B6E240B81A4001EA5EB /* AppDelegate.swift in Sources */, DA1A6B70240B81A4001EA5EB /* SceneDelegate.swift in Sources */, DA1A6B72240B81A4001EA5EB /* ContentView.swift in Sources */, diff --git a/DemoApp/DemoApp/ContentView.swift b/DemoApp/DemoApp/ContentView.swift index be171f4..b06412f 100644 --- a/DemoApp/DemoApp/ContentView.swift +++ b/DemoApp/DemoApp/ContentView.swift @@ -17,11 +17,11 @@ struct ContentView: View { .font(.title) .foregroundColor(self.neumorphism.color.darkerColor()) - NeumorphismButton() { + NeumorphismButton(shapeType: .circle) { self.neumorphism.changeMode() } - NeumorphismButton(normalImage: Image(systemName: "star"), selectedImage: Image(systemName: "star.fill")) + NeumorphismButton(shapeType: .roundedRectangle(cornerRadius: 20), normalImage: Image(systemName: "star"), selectedImage: Image(systemName: "star.fill")) Circle() .fill(self.neumorphism.color) diff --git a/DemoApp/DemoApp/NeumorphismRoundedRectangleButton.swift b/DemoApp/DemoApp/NeumorphismRoundedRectangleButton.swift deleted file mode 100644 index daac09d..0000000 --- a/DemoApp/DemoApp/NeumorphismRoundedRectangleButton.swift +++ /dev/null @@ -1,35 +0,0 @@ -import SwiftUI -import NeumorphismUI - -struct NeumorphismRoundedRectangleButton: View { - @EnvironmentObject var neumorphism: NeumorphismManager - @State var isSelectedBox = false - - var body: some View { - HighlightableButton(action: { - self.isSelectedBox.toggle() - }) { isHeighlight in - Image(systemName: self.isSelectedBox ? "heart.fill" : "heart") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width:60, height: 60) - .foregroundColor(self.neumorphism.color.darkerColor()) - .background( - RoundedRectangle(cornerRadius: 20) - .fill(self.neumorphism.color) - .frame(width: 100, height: 100) - .modifier(NeumorphismShadowModifier(isAnimation: isHeighlight)) - ) - .padding() - .animation(Animation.spring(response: 0.3, dampingFraction: 0.7, blendDuration: 1)) - - } - .padding() - } -} - -struct NeumorphismRoundedRectangleButton_Previews: PreviewProvider { - static var previews: some View { - NeumorphismRoundedRectangleButton() - } -} diff --git a/NeumorphismUI.xcodeproj/project.pbxproj b/NeumorphismUI.xcodeproj/project.pbxproj index 939b4f3..2abcaea 100644 --- a/NeumorphismUI.xcodeproj/project.pbxproj +++ b/NeumorphismUI.xcodeproj/project.pbxproj @@ -22,6 +22,8 @@ /* Begin PBXBuildFile section */ DA5AFAC9241691210098E0BB /* NeumorphismButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5AFAC8241691210098E0BB /* NeumorphismButton.swift */; }; + DA5AFACD2418332A0098E0BB /* ShapeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5AFACC2418332A0098E0BB /* ShapeType.swift */; }; + DA5AFACF241833430098E0BB /* AnyShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5AFACE241833430098E0BB /* AnyShape.swift */; }; DA90AF652412D01900E759A9 /* NeumorphismManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA90AF642412D01900E759A9 /* NeumorphismManagerTests.swift */; }; DA90AF682412D0EE00E759A9 /* NeumorphismManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA90AF672412D0EE00E759A9 /* NeumorphismManagerMock.swift */; }; DA954C782411D9740052B8FF /* NeumorphismManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA954C772411D9740052B8FF /* NeumorphismManager.swift */; }; @@ -55,6 +57,8 @@ /* Begin PBXFileReference section */ DA1A6B5F240B76D9001EA5EB /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; DA5AFAC8241691210098E0BB /* NeumorphismButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphismButton.swift; sourceTree = ""; }; + DA5AFACC2418332A0098E0BB /* ShapeType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShapeType.swift; sourceTree = ""; }; + DA5AFACE241833430098E0BB /* AnyShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyShape.swift; sourceTree = ""; }; DA90AF642412D01900E759A9 /* NeumorphismManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphismManagerTests.swift; sourceTree = ""; }; DA90AF672412D0EE00E759A9 /* NeumorphismManagerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphismManagerMock.swift; sourceTree = ""; }; DA954C772411D9740052B8FF /* NeumorphismManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphismManager.swift; sourceTree = ""; }; @@ -162,6 +166,8 @@ DA954C772411D9740052B8FF /* NeumorphismManager.swift */, OBJ_9 /* ColorTransformer.swift */, OBJ_13 /* NeumorphismShadowModifier.swift */, + DA5AFACE241833430098E0BB /* AnyShape.swift */, + DA5AFACC2418332A0098E0BB /* ShapeType.swift */, DA987319240BDE580083EB5E /* CustomViews */, OBJ_10 /* Extensions */, ); @@ -258,8 +264,10 @@ DA90AF682412D0EE00E759A9 /* NeumorphismManagerMock.swift in Sources */, DA954C782411D9740052B8FF /* NeumorphismManager.swift in Sources */, DA5AFAC9241691210098E0BB /* NeumorphismButton.swift in Sources */, + DA5AFACD2418332A0098E0BB /* ShapeType.swift in Sources */, OBJ_32 /* ViewExtension.swift in Sources */, OBJ_33 /* NeumorphismShadowModifier.swift in Sources */, + DA5AFACF241833430098E0BB /* AnyShape.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Sources/AnyShape.swift b/Sources/AnyShape.swift new file mode 100644 index 0000000..928ddc6 --- /dev/null +++ b/Sources/AnyShape.swift @@ -0,0 +1,17 @@ +import SwiftUI + +@available(iOS 13.0.0, *) +public struct AnyShape: Shape { + public init(_ wrapped: S) { + _path = { rect in + let path = wrapped.path(in: rect) + return path + } + } + + public func path(in rect: CGRect) -> Path { + return _path(rect) + } + + private let _path: (CGRect) -> Path +} diff --git a/Sources/CustomViews/NeumorphismButton.swift b/Sources/CustomViews/NeumorphismButton.swift index ca0bc4e..c068ade 100644 --- a/Sources/CustomViews/NeumorphismButton.swift +++ b/Sources/CustomViews/NeumorphismButton.swift @@ -4,7 +4,8 @@ import SwiftUI public struct NeumorphismButton: View { @EnvironmentObject var neumorphism: NeumorphismManager @State var isSelected = false - + + private var shapeType: ShapeType private var normalImage: Image private var selectedImage: Image private var width: CGFloat @@ -12,9 +13,10 @@ public struct NeumorphismButton: View { private var imageWidth: CGFloat private var imageHeight: CGFloat private var handler: (() -> Void)? - + public init ( + shapeType: ShapeType = .circle, normalImage: Image = Image(systemName: "heart"), selectedImage: Image = Image(systemName: "heart.fill"), width: CGFloat = 100, @@ -23,6 +25,7 @@ public struct NeumorphismButton: View { imageHeight: CGFloat = 60, handler: (() -> Void)? = nil ) { + self.shapeType = shapeType self.normalImage = normalImage self.selectedImage = selectedImage self.width = width @@ -43,8 +46,9 @@ public struct NeumorphismButton: View { .frame(width:self.imageWidth, height: self.imageWidth) .foregroundColor(self.neumorphism.color.darkerColor()) .background( - Circle() - .fill(self.neumorphism.color) + Rectangle() + .clipShape(self.getAnyShape(type: self.shapeType)) + .foregroundColor(self.neumorphism.color) .frame(width: self.width, height: self.height) .modifier(NeumorphismShadowModifier(isAnimation: isHeighlight)) ) @@ -53,4 +57,20 @@ public struct NeumorphismButton: View { } .padding() } + + public func getAnyShape(type: ShapeType) -> AnyShape { + switch type { + case .rectangle: + return AnyShape(Rectangle()) + case .roundedRectangle(let cornerRadius): + return AnyShape(RoundedRectangle(cornerRadius: cornerRadius)) + case .capsule: + return AnyShape(Capsule(style: .circular)) + case .ellipse: + return AnyShape(Ellipse()) + case .circle: + return AnyShape(Circle()) + } + } } + diff --git a/Sources/Extensions/ViewExtension.swift b/Sources/Extensions/ViewExtension.swift index e1b7780..e358a55 100644 --- a/Sources/Extensions/ViewExtension.swift +++ b/Sources/Extensions/ViewExtension.swift @@ -2,7 +2,7 @@ import SwiftUI @available(iOS 13.0, *) public extension View { - func neumorphismShadow() -> some View { - self.modifier(NeumorphismShadowModifier()) + func neumorphismShadow(isAnimation: Bool = false) -> some View { + self.modifier(NeumorphismShadowModifier(isAnimation: isAnimation)) } } diff --git a/Sources/ShapeType.swift b/Sources/ShapeType.swift new file mode 100644 index 0000000..0f8353a --- /dev/null +++ b/Sources/ShapeType.swift @@ -0,0 +1,9 @@ +import SwiftUI + +public enum ShapeType { + case rectangle + case roundedRectangle(cornerRadius: CGFloat) + case capsule + case ellipse + case circle +}