Skip to content

Commit

Permalink
Add preset .exclamation
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanvorobei committed Nov 28, 2019
1 parent 4c0a9bd commit 9725adc
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 2 deletions.
10 changes: 10 additions & 0 deletions Assets/Readme/Miniature - Exclamation.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Assets/Sketch/Presets.sketch
Binary file not shown.
12 changes: 12 additions & 0 deletions Example/Controllers/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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: "Exclamation", preset: .exclamation, title: "Oops", subtitle: "Something went wrong"),
Alert(key: "Add", preset: .add, title: "Added to Folder", subtitle: nil),
Alert(key: "Error", preset: .error, title: "Oops", subtitle: "Please try again later"),
Alert(key: "Message", preset: nil, title: nil, subtitle: "Email required")
Expand Down Expand Up @@ -46,6 +47,9 @@ class ViewController: UITableViewController {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}

/**
Show now. Call when tap on nav-bar item.
*/
@objc func showAlert() {
let alertData = data[selectedIndexPath.row]
if let preset = alertData.preset {
Expand All @@ -55,6 +59,14 @@ class ViewController: UITableViewController {
}
}

/**
Alert preview data.

- parameter key: Visible ID in table view.
- parameter preset: Preset for `SPAlert`.
- parameter title: Title in `SPAlert`. Optional only for `.message` preset.
- parameter subtitle: Optional subtitle in `SPAlert`.
*/
typealias Alert = (key: String, preset: SPAlertPreset?, title: String?, subtitle: String?)
}

Expand Down
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ And other
<img src="https://github.com/ivanvorobei/SPAlert/blob/master/Assets/Readme/Miniature%20-%20Bookmark.svg" width="55">
<img src="https://github.com/ivanvorobei/SPAlert/blob/master/Assets/Readme/Miniature%20-%20Moon.svg" width="55">
<img src="https://github.com/ivanvorobei/SPAlert/blob/master/Assets/Readme/Miniature%20-%20Star.svg" width="55">
<img src="https://github.com/ivanvorobei/SPAlert/blob/master/Assets/Readme/Miniature%20-%20Exclamation.svg" width="55">
<img src="https://github.com/ivanvorobei/SPAlert/blob/master/Assets/Readme/Miniature%20-%20Add.svg" width="55">
<img src="https://github.com/ivanvorobei/SPAlert/blob/master/Assets/Readme/Miniature%20-%20Error.svg" width="55">
</p>
Expand Down
4 changes: 2 additions & 2 deletions SPAlert.podspec
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Pod::Spec.new do |s|

s.name = "SPAlert"
s.version = "2.0.6"
s.summary = "Native alert from Apple Music & Feedback. Contains Done, Heart & Message presets."
s.version = "2.0.8"
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 }
s.license = { :type => "MIT", :file => "LICENSE" }
Expand Down
4 changes: 4 additions & 0 deletions SPAlert.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
F4CA67B5238ABD0100E72F79 /* SPAlertIconAddView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CA67B4238ABD0100E72F79 /* SPAlertIconAddView.swift */; };
F4D3CD58238DA9FE006C3DE2 /* SPAlertIconMoonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4D3CD57238DA9FE006C3DE2 /* SPAlertIconMoonView.swift */; };
F4D3CD5A238DAA49006C3DE2 /* SPAlertIconStarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4D3CD59238DAA49006C3DE2 /* SPAlertIconStarView.swift */; };
F4E4459D2390524A0067FF5C /* SPAlertIconExclamationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4E4459C2390524A0067FF5C /* SPAlertIconExclamationView.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -84,6 +85,7 @@
F4CA67B4238ABD0100E72F79 /* SPAlertIconAddView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAlertIconAddView.swift; sourceTree = "<group>"; };
F4D3CD57238DA9FE006C3DE2 /* SPAlertIconMoonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAlertIconMoonView.swift; sourceTree = "<group>"; };
F4D3CD59238DAA49006C3DE2 /* SPAlertIconStarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAlertIconStarView.swift; sourceTree = "<group>"; };
F4E4459C2390524A0067FF5C /* SPAlertIconExclamationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAlertIconExclamationView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -169,6 +171,7 @@
F4CA67B4238ABD0100E72F79 /* SPAlertIconAddView.swift */,
F4D3CD57238DA9FE006C3DE2 /* SPAlertIconMoonView.swift */,
F4D3CD59238DAA49006C3DE2 /* SPAlertIconStarView.swift */,
F4E4459C2390524A0067FF5C /* SPAlertIconExclamationView.swift */,
);
path = Icons;
sourceTree = "<group>";
Expand Down Expand Up @@ -366,6 +369,7 @@
files = (
F412052A2382AF64009C2AC7 /* SPAlertHaptic.swift in Sources */,
F41204EE2382AC9B009C2AC7 /* SPAlert.swift in Sources */,
F4E4459D2390524A0067FF5C /* SPAlertIconExclamationView.swift in Sources */,
F41204EA2382AC9B009C2AC7 /* SPAlertPreset.swift in Sources */,
F4A5A92C2388792F00B0DFE0 /* SPAlertIconBookmarkView.swift in Sources */,
F41204EC2382AC9B009C2AC7 /* SPAlertIconDoneView.swift in Sources */,
Expand Down
13 changes: 13 additions & 0 deletions Source/SPAlert/Models/SPAlertPreset.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public enum SPAlertPreset {
case bookmark
case moon
case star
case exclamation
case add
case error

Expand All @@ -52,6 +53,8 @@ public enum SPAlertPreset {
return SPAlertIconAddView()
case .moon:
return SPAlertIconMoonView()
case .exclamation:
return SPAlertIconExclamationView()
case .star:
return SPAlertIconStarView()
case .error:
Expand Down Expand Up @@ -80,6 +83,14 @@ public enum SPAlertPreset {
layout.iconHeight = 77
layout.bottomIconSpace = 35
return layout
case .exclamation:
var layout = SPAlertLayout()
layout.topSpace = 46
layout.bottomSpace = 33
layout.iconWidth = 112
layout.iconHeight = 90
layout.bottomIconSpace = 31
return layout
case .doc:
var layout = SPAlertLayout()
layout.topSpace = 49
Expand Down Expand Up @@ -150,6 +161,8 @@ public enum SPAlertPreset {
return .success
case .moon:
return .success
case .exclamation:
return .warning
case .error:
return .error
}
Expand Down
119 changes: 119 additions & 0 deletions Source/SPAlert/Views/Icons/SPAlertIconExclamationView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// The MIT License (MIT)
// Copyright © 2019 Ivan Vorobei ([email protected])
//
// 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 SPAlertIconExclamationView: 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)
ExclamationDraw.draw(frame: rect, resizing: .aspectFit, fillColor: self.tintColor)
}

class ExclamationDraw: NSObject {

@objc dynamic public class func draw(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 65, height: 65), 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: 58, height: 52), target: targetFrame)
context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY)
context.scaleBy(x: resizedFrame.width / 58, y: resizedFrame.height / 52)
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 9.05, y: 50))
bezierPath.addLine(to: CGPoint(x: 48.02, y: 50))
bezierPath.addCurve(to: CGPoint(x: 54.07, y: 43.95), controlPoint1: CGPoint(x: 51.74, y: 50), controlPoint2: CGPoint(x: 54.07, y: 47.32))
bezierPath.addCurve(to: CGPoint(x: 53.27, y: 40.97), controlPoint1: CGPoint(x: 54.07, y: 42.93), controlPoint2: CGPoint(x: 53.82, y: 41.91))
bezierPath.addLine(to: CGPoint(x: 33.75, y: 6.05))
bezierPath.addCurve(to: CGPoint(x: 28.55, y: 3), controlPoint1: CGPoint(x: 32.64, y: 4.04), controlPoint2: CGPoint(x: 30.58, y: 3))
bezierPath.addCurve(to: CGPoint(x: 23.31, y: 6.05), controlPoint1: CGPoint(x: 26.49, y: 3), controlPoint2: CGPoint(x: 24.43, y: 4.04))
bezierPath.addLine(to: CGPoint(x: 3.82, y: 41))
bezierPath.addCurve(to: CGPoint(x: 3, y: 43.95), controlPoint1: CGPoint(x: 3.27, y: 41.94), controlPoint2: CGPoint(x: 3, y: 42.93))
bezierPath.addCurve(to: CGPoint(x: 9.05, y: 50), controlPoint1: CGPoint(x: 3, y: 47.32), controlPoint2: CGPoint(x: 5.33, y: 50))
bezierPath.close()
bezierPath.move(to: CGPoint(x: 28.55, y: 33.01))
bezierPath.addCurve(to: CGPoint(x: 26.46, y: 30.93), controlPoint1: CGPoint(x: 27.23, y: 33.01), controlPoint2: CGPoint(x: 26.51, y: 32.27))
bezierPath.addLine(to: CGPoint(x: 26.12, y: 18.67))
bezierPath.addCurve(to: CGPoint(x: 28.52, y: 16.34), controlPoint1: CGPoint(x: 26.07, y: 17.34), controlPoint2: CGPoint(x: 27.11, y: 16.34))
bezierPath.addCurve(to: CGPoint(x: 30.93, y: 18.7), controlPoint1: CGPoint(x: 29.91, y: 16.34), controlPoint2: CGPoint(x: 30.98, y: 17.36))
bezierPath.addLine(to: CGPoint(x: 30.58, y: 30.93))
bezierPath.addCurve(to: CGPoint(x: 28.55, y: 33.01), controlPoint1: CGPoint(x: 30.53, y: 32.29), controlPoint2: CGPoint(x: 29.79, y: 33.01))
bezierPath.close()
bezierPath.move(to: CGPoint(x: 28.55, y: 42.16))
bezierPath.addCurve(to: CGPoint(x: 25.77, y: 39.48), controlPoint1: CGPoint(x: 27.11, y: 42.16), controlPoint2: CGPoint(x: 25.77, y: 41.02))
bezierPath.addCurve(to: CGPoint(x: 28.55, y: 36.81), controlPoint1: CGPoint(x: 25.77, y: 37.95), controlPoint2: CGPoint(x: 27.08, y: 36.81))
bezierPath.addCurve(to: CGPoint(x: 31.32, y: 39.48), controlPoint1: CGPoint(x: 29.98, y: 36.81), controlPoint2: CGPoint(x: 31.32, y: 37.92))
bezierPath.addCurve(to: CGPoint(x: 28.55, y: 42.16), controlPoint1: CGPoint(x: 31.32, y: 41.05), controlPoint2: CGPoint(x: 29.96, y: 42.16))
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
}
}
}
}

0 comments on commit 9725adc

Please sign in to comment.