diff --git a/Assets/Readme/Miniature - Flag.svg b/Assets/Readme/Miniature - Flag.svg new file mode 100644 index 0000000..2b2fe40 --- /dev/null +++ b/Assets/Readme/Miniature - Flag.svg @@ -0,0 +1,10 @@ + + + + Miniature - Flag + Created with Sketch. + + + + + \ No newline at end of file diff --git a/Assets/Sketch/Presets.sketch b/Assets/Sketch/Presets.sketch index 02f881a..17864cb 100644 Binary files a/Assets/Sketch/Presets.sketch and b/Assets/Sketch/Presets.sketch differ diff --git a/Example/Controllers/ViewController.swift b/Example/Controllers/ViewController.swift index 3aae3ce..9589dfc 100644 --- a/Example/Controllers/ViewController.swift +++ b/Example/Controllers/ViewController.swift @@ -10,6 +10,7 @@ class ViewController: UITableViewController { Alert(key: "Bookmark", preset: .bookmark, title: "Added to bookmark", subtitle: "See bookmarks screen"), Alert(key: "Moon", preset: .moon, title: "Night Mode", subtitle: "You can disable it in settings"), Alert(key: "Star", preset: .star, title: "Added to favorite", subtitle: nil), + Alert(key: "Flag", preset: .flag, title: "Message Flaged", subtitle: nil), Alert(key: "Exclamation", preset: .exclamation, title: "Oops", subtitle: "Something went wrong"), Alert(key: "Message", preset: .message, title: "Message sended", subtitle: "You can check history"), Alert(key: "Add", preset: .add, title: "Added to Folder", subtitle: nil), diff --git a/Readme.md b/Readme.md index 6cd2df6..d4950f1 100644 --- a/Readme.md +++ b/Readme.md @@ -15,6 +15,7 @@ And other + diff --git a/SPAlert.podspec b/SPAlert.podspec index 0b38183..a342432 100644 --- a/SPAlert.podspec +++ b/SPAlert.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "SPAlert" - s.version = "2.0.11" + s.version = "2.0.12" s.summary = "Native alert from Apple Music & Feedback. Contains Done, Heart & Message and other presets." s.homepage = "https://github.com/IvanVorobei/SPAlert" s.source = { :git => "https://github.com/IvanVorobei/SPAlert.git", :tag => s.version } diff --git a/SPAlert.xcodeproj/project.pbxproj b/SPAlert.xcodeproj/project.pbxproj index e68bb4c..3a98b81 100644 --- a/SPAlert.xcodeproj/project.pbxproj +++ b/SPAlert.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ F41205292382AF5C009C2AC7 /* SPAlertIconAnimatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41205262382AF29009C2AC7 /* SPAlertIconAnimatable.swift */; }; F412052A2382AF64009C2AC7 /* SPAlertHaptic.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41204E42382AC9B009C2AC7 /* SPAlertHaptic.swift */; }; F412052B2382AF64009C2AC7 /* SPAlertLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41205222382AEFA009C2AC7 /* SPAlertLayout.swift */; }; + F421EFF12398684E000A566D /* SPAlertIconFlagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F421EFF02398684E000A566D /* SPAlertIconFlagView.swift */; }; F46AAEFE2392E97200BE9131 /* SPAlertIconMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46AAEFD2392E97200BE9131 /* SPAlertIconMessageView.swift */; }; F47EE19D23959ADB00B02DF2 /* SPAlertIconShuffleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F47EE19C23959ADB00B02DF2 /* SPAlertIconShuffleView.swift */; }; F47EE19F23959AE500B02DF2 /* SPAlertIconRepeatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F47EE19E23959AE500B02DF2 /* SPAlertIconRepeatView.swift */; }; @@ -83,6 +84,7 @@ F41205182382AD8B009C2AC7 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; F41205222382AEFA009C2AC7 /* SPAlertLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAlertLayout.swift; sourceTree = ""; }; F41205262382AF29009C2AC7 /* SPAlertIconAnimatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAlertIconAnimatable.swift; sourceTree = ""; }; + F421EFF02398684E000A566D /* SPAlertIconFlagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAlertIconFlagView.swift; sourceTree = ""; }; F46AAEFD2392E97200BE9131 /* SPAlertIconMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAlertIconMessageView.swift; sourceTree = ""; }; F47EE19C23959ADB00B02DF2 /* SPAlertIconShuffleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAlertIconShuffleView.swift; sourceTree = ""; }; F47EE19E23959AE500B02DF2 /* SPAlertIconRepeatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAlertIconRepeatView.swift; sourceTree = ""; }; @@ -181,6 +183,7 @@ F46AAEFD2392E97200BE9131 /* SPAlertIconMessageView.swift */, F47EE19C23959ADB00B02DF2 /* SPAlertIconShuffleView.swift */, F47EE19E23959AE500B02DF2 /* SPAlertIconRepeatView.swift */, + F421EFF02398684E000A566D /* SPAlertIconFlagView.swift */, ); path = Icons; sourceTree = ""; @@ -383,6 +386,7 @@ F4A5A92C2388792F00B0DFE0 /* SPAlertIconBookmarkView.swift in Sources */, F41204EC2382AC9B009C2AC7 /* SPAlertIconDoneView.swift in Sources */, F41204E92382AC9B009C2AC7 /* SPAlertView.swift in Sources */, + F421EFF12398684E000A566D /* SPAlertIconFlagView.swift in Sources */, F47EE19D23959ADB00B02DF2 /* SPAlertIconShuffleView.swift in Sources */, F4D3CD58238DA9FE006C3DE2 /* SPAlertIconMoonView.swift in Sources */, F4D3CD5A238DAA49006C3DE2 /* SPAlertIconStarView.swift in Sources */, diff --git a/Source/SPAlert/Models/SPAlertPreset.swift b/Source/SPAlert/Models/SPAlertPreset.swift index 3373f0d..3c2826c 100644 --- a/Source/SPAlert/Models/SPAlertPreset.swift +++ b/Source/SPAlert/Models/SPAlertPreset.swift @@ -33,6 +33,7 @@ public enum SPAlertPreset { case moon case star case exclamation + case flag case message case add case error @@ -68,6 +69,8 @@ public enum SPAlertPreset { return SPAlertIconShuffleView() case .repeat: return SPAlertIconRepeatView() + case .flag: + return SPAlertIconFlagView() } } @@ -116,6 +119,14 @@ public enum SPAlertPreset { layout.iconHeight = 77 layout.bottomIconSpace = 35 return layout + case .flag: + var layout = SPAlertLayout() + layout.topSpace = 49 + layout.bottomSpace = 31 + layout.iconWidth = 112 + layout.iconHeight = 88 + layout.bottomIconSpace = 35 + return layout case .bookmark: var layout = SPAlertLayout() layout.topSpace = 57 @@ -204,6 +215,8 @@ public enum SPAlertPreset { return .success case .repeat: return .success + case .flag: + return .success } } } diff --git a/Source/SPAlert/Views/Icons/SPAlertIconFlagView.swift b/Source/SPAlert/Views/Icons/SPAlertIconFlagView.swift new file mode 100644 index 0000000..af10fdd --- /dev/null +++ b/Source/SPAlert/Views/Icons/SPAlertIconFlagView.swift @@ -0,0 +1,112 @@ +// The MIT License (MIT) +// Copyright © 2019 Ivan Vorobei (ivanvorobei@icloud.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 UIKit + +public class SPAlertIconFlagView: UIView { + + init() { + super.init(frame: .zero) + self.backgroundColor = .clear + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public override func draw(_ rect: CGRect) { + super.draw(rect) + ShuffleDraw.draw(frame: rect, resizing: .aspectFit, fillColor: self.tintColor) + } + + class ShuffleDraw: NSObject { + + @objc dynamic public class func draw(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 60, height: 56), resizing: ResizingBehavior = .aspectFit, fillColor: UIColor = UIColor(red: 0.349, green: 0.345, blue: 0.353, alpha: 1.000)) { + let context = UIGraphicsGetCurrentContext()! + context.saveGState() + let resizedFrame: CGRect = resizing.apply(rect: CGRect(x: 0, y: 0, width: 51, height: 55), target: targetFrame) + context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY) + context.scaleBy(x: resizedFrame.width / 51, y: resizedFrame.height / 55) + let bezierPath = UIBezierPath() + bezierPath.move(to: CGPoint(x: 3.94, y: 53)) + bezierPath.addCurve(to: CGPoint(x: 2, y: 51.09), controlPoint1: CGPoint(x: 2.89, y: 53), controlPoint2: CGPoint(x: 2, y: 52.13)) + bezierPath.addLine(to: CGPoint(x: 2, y: 8.73)) + bezierPath.addCurve(to: CGPoint(x: 4.91, y: 4.3), controlPoint1: CGPoint(x: 2, y: 6.41), controlPoint2: CGPoint(x: 3.15, y: 5.09)) + bezierPath.addLine(to: CGPoint(x: 5.25, y: 4.15)) + bezierPath.addCurve(to: CGPoint(x: 12.32, y: 3), controlPoint1: CGPoint(x: 7.03, y: 3.38), controlPoint2: CGPoint(x: 8.59, y: 3)) + bezierPath.addCurve(to: CGPoint(x: 36.63, y: 7.61), controlPoint1: CGPoint(x: 21.78, y: 3), controlPoint2: CGPoint(x: 27.66, y: 7.61)) + bezierPath.addCurve(to: CGPoint(x: 44.61, y: 6.54), controlPoint1: CGPoint(x: 41.02, y: 7.61), controlPoint2: CGPoint(x: 43.36, y: 6.54)) + bezierPath.addCurve(to: CGPoint(x: 47.26, y: 8.71), controlPoint1: CGPoint(x: 46.09, y: 6.54), controlPoint2: CGPoint(x: 47.26, y: 7.33)) + bezierPath.addLine(to: CGPoint(x: 47.26, y: 34.57)) + bezierPath.addCurve(to: CGPoint(x: 44.35, y: 39.03), controlPoint1: CGPoint(x: 47.26, y: 36.92), controlPoint2: CGPoint(x: 46.11, y: 38.24)) + bezierPath.addLine(to: CGPoint(x: 44.01, y: 39.19)) + bezierPath.addCurve(to: CGPoint(x: 36.96, y: 40.33), controlPoint1: CGPoint(x: 42.23, y: 39.95), controlPoint2: CGPoint(x: 40.7, y: 40.33)) + bezierPath.addCurve(to: CGPoint(x: 12.65, y: 35.72), controlPoint1: CGPoint(x: 27.99, y: 40.33), controlPoint2: CGPoint(x: 22.08, y: 35.72)) + bezierPath.addCurve(to: CGPoint(x: 5.87, y: 36.92), controlPoint1: CGPoint(x: 8.91, y: 35.72), controlPoint2: CGPoint(x: 6.51, y: 36.64)) + bezierPath.addLine(to: CGPoint(x: 5.87, y: 51.09)) + bezierPath.addCurve(to: CGPoint(x: 3.94, y: 53), controlPoint1: CGPoint(x: 5.87, y: 52.16), controlPoint2: CGPoint(x: 5.01, y: 53)) + bezierPath.close() + fillColor.setFill() + bezierPath.fill() + context.restoreGState() + } + + @objc(StyleKitNameResizingBehavior) + public enum ResizingBehavior: Int { + + case aspectFit + case aspectFill + case stretch + case center + + public func apply(rect: CGRect, target: CGRect) -> CGRect { + if rect == target || target == CGRect.zero { + return rect + } + + var scales = CGSize.zero + scales.width = abs(target.width / rect.width) + scales.height = abs(target.height / rect.height) + + switch self { + case .aspectFit: + scales.width = min(scales.width, scales.height) + scales.height = scales.width + case .aspectFill: + scales.width = max(scales.width, scales.height) + scales.height = scales.width + case .stretch: + break + case .center: + scales.width = 1 + scales.height = 1 + } + + var result = rect.standardized + result.size.width *= scales.width + result.size.height *= scales.height + result.origin.x = target.minX + (target.width - result.width) / 2 + result.origin.y = target.minY + (target.height - result.height) / 2 + return result + } + } + } +}