Skip to content
This repository has been archived by the owner on Jul 20, 2023. It is now read-only.

Feature/highlighting overlay #209

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions EasyTipView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
1310EC961D0C53800000E71E /* EasyTipView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1310EC8B1D0C537F0000E71E /* EasyTipView.framework */; };
13FB32A91D0C53E5001ACE20 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FB32A61D0C53E2001ACE20 /* Tests.swift */; };
3D0E3EA525FA2CC600899BB7 /* TipViewHighlightingBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D0E3EA425FA2CC600899BB7 /* TipViewHighlightingBackground.swift */; };
3DEF6DAB23A39E4F007B8C3C /* EasyTipView.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DEF6DA823A39E4F007B8C3C /* EasyTipView.h */; settings = {ATTRIBUTES = (Public, ); }; };
3DEF6DAC23A39E4F007B8C3C /* UIKitExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DEF6DA923A39E4F007B8C3C /* UIKitExtensions.swift */; };
3DEF6DAD23A39E4F007B8C3C /* EasyTipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DEF6DAA23A39E4F007B8C3C /* EasyTipView.swift */; };
Expand All @@ -30,6 +31,7 @@
13FB32A11D0C53CB001ACE20 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Sources/EasyTipView/info.plist; sourceTree = SOURCE_ROOT; };
13FB32A51D0C53E2001ACE20 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Tests/Info.plist; sourceTree = SOURCE_ROOT; };
13FB32A61D0C53E2001ACE20 /* Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Tests.swift; path = Tests/EasyTipViewTests/Tests.swift; sourceTree = SOURCE_ROOT; };
3D0E3EA425FA2CC600899BB7 /* TipViewHighlightingBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TipViewHighlightingBackground.swift; sourceTree = "<group>"; };
3DEF6DA823A39E4F007B8C3C /* EasyTipView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EasyTipView.h; sourceTree = "<group>"; };
3DEF6DA923A39E4F007B8C3C /* UIKitExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIKitExtensions.swift; sourceTree = "<group>"; };
3DEF6DAA23A39E4F007B8C3C /* EasyTipView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EasyTipView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -96,6 +98,7 @@
3DEF6DA823A39E4F007B8C3C /* EasyTipView.h */,
3DEF6DAA23A39E4F007B8C3C /* EasyTipView.swift */,
3DEF6DA923A39E4F007B8C3C /* UIKitExtensions.swift */,
3D0E3EA425FA2CC600899BB7 /* TipViewHighlightingBackground.swift */,
);
path = EasyTipView;
sourceTree = "<group>";
Expand Down Expand Up @@ -220,6 +223,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3D0E3EA525FA2CC600899BB7 /* TipViewHighlightingBackground.swift in Sources */,
3DEF6DAD23A39E4F007B8C3C /* EasyTipView.swift in Sources */,
3DEF6DAC23A39E4F007B8C3C /* UIKitExtensions.swift in Sources */,
);
Expand Down
32 changes: 30 additions & 2 deletions Example/EasyTipView/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="t2B-Ub-hJ7">
<rect key="frame" x="114.5" y="184.5" width="46" height="30"/>
<color key="backgroundColor" red="0.20999990459177764" green="0.64271100905717482" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" red="0.21176470588235294" green="0.64313725490196072" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="Huo-8Y-VFk"/>
<constraint firstAttribute="width" constant="46" id="bpW-qX-mX4"/>
Expand Down Expand Up @@ -199,6 +199,27 @@
<action selector="buttonActionWithSender:" destination="7mQ-RG-Clx" eventType="touchUpInside" id="fUK-oR-Pnv"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gfZ-et-If5" userLabel="ButtonH">
<rect key="frame" x="329" y="114" width="30" height="30"/>
<color key="backgroundColor" red="0.21176470588235294" green="0.64313725490196072" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="3lf-zS-2SH"/>
<constraint firstAttribute="height" constant="30" id="78G-IW-7yF"/>
</constraints>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" image="info.circle" catalog="system">
<color key="titleColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="3"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="buttonActionWithSender:" destination="7mQ-RG-Clx" eventType="touchUpInside" id="ohx-MO-csS"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
Expand All @@ -218,11 +239,13 @@
<constraint firstItem="jYe-y0-pin" firstAttribute="top" secondItem="hWU-jR-9Ec" secondAttribute="bottom" constant="25" id="eb5-de-OnU"/>
<constraint firstAttribute="trailing" secondItem="jYe-y0-pin" secondAttribute="trailing" id="jz0-h5-eWe"/>
<constraint firstAttribute="centerY" secondItem="NUT-CX-WGP" secondAttribute="centerY" id="p7a-iN-6vS"/>
<constraint firstItem="gfZ-et-If5" firstAttribute="top" secondItem="lCx-tc-eXO" secondAttribute="bottom" constant="20" id="uhL-Ri-ED2"/>
<constraint firstAttribute="trailing" secondItem="gfZ-et-If5" secondAttribute="trailing" constant="16" id="vCl-Hb-e4I"/>
<constraint firstItem="JdK-KQ-BEN" firstAttribute="leading" secondItem="K9k-ME-Y4A" secondAttribute="leadingMargin" id="xZL-MK-bZb"/>
</constraints>
</view>
<navigationItem key="navigationItem" title="EasyTipView - Demo" id="gPI-yp-aVH">
<barButtonItem key="rightBarButtonItem" title="↓" id="HcR-vd-SJ7">
<barButtonItem key="rightBarButtonItem" image="arrow.down.circle" catalog="system" id="HcR-vd-SJ7">
<connections>
<action selector="barButtonActionWithSender:" destination="7mQ-RG-Clx" id="DWI-ft-6oN"/>
</connections>
Expand All @@ -236,6 +259,7 @@
<outlet property="buttonE" destination="lCx-tc-eXO" id="Gyl-pL-7Dw"/>
<outlet property="buttonF" destination="t2B-Ub-hJ7" id="Uzp-Qd-E26"/>
<outlet property="buttonG" destination="HS8-yg-j4l" id="sv7-RK-cGC"/>
<outlet property="buttonH" destination="gfZ-et-If5" id="InF-wX-ENn"/>
<outlet property="navBarItem" destination="HcR-vd-SJ7" id="PXK-2J-bNl"/>
<outlet property="smallContainerView" destination="NUT-CX-WGP" id="AO3-b9-Iky"/>
<outlet property="toolbarItem" destination="L9z-Ee-Hcj" id="cow-BG-IkN"/>
Expand Down Expand Up @@ -265,4 +289,8 @@
<point key="canvasLocation" x="1197" y="-264"/>
</scene>
</scenes>
<resources>
<image name="arrow.down.circle" catalog="system" width="128" height="121"/>
<image name="info.circle" catalog="system" width="128" height="121"/>
</resources>
</document>
22 changes: 22 additions & 0 deletions Example/EasyTipView/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ViewController: UIViewController, EasyTipViewDelegate {
@IBOutlet weak var buttonE: UIButton!
@IBOutlet weak var buttonF: UIButton!
@IBOutlet weak var buttonG: UIButton!
@IBOutlet weak var buttonH: UIButton!

weak var tipView: EasyTipView?

Expand Down Expand Up @@ -211,6 +212,27 @@ class ViewController: UIViewController, EasyTipViewDelegate {
EasyTipView.show(forView: self.buttonG,
contentView: contentView,
preferences: preferences)

case buttonH:

var preferences = EasyTipView.Preferences()
preferences.drawing.backgroundColor = buttonH.backgroundColor!
preferences.drawing.foregroundColor = UIColor.white
preferences.drawing.textAlignment = NSTextAlignment.center

preferences.drawing.arrowPosition = .top
preferences.animating.showInitialAlpha = 0
preferences.animating.showDuration = 0.7
preferences.animating.dismissDuration = 0.7
preferences.animating.dismissOnTap = true

preferences.positioning.maxWidth = 150
preferences.positioning.bubbleInsets = UIEdgeInsets(top: 10, left: 0, bottom: 0, right: 4)

preferences.highlighting.showsOverlay = true

let view = EasyTipView(text: "Tip view with highlighting overlay", preferences: preferences)
view.show(forView: buttonH, withinSuperview: self.navigationController?.view!)

default:

Expand Down
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Description
- [x] Automatic orientation change adjustments.
- [x] Fully customizable appearance (custom content view or simply just text - including `NSAttributedString` - see the Example app).
- [x] Fully customizable presentation and dismissal animations.
- [x] Optional highlighting overlay.


<a name="installation"> Installation </a>
Expand Down Expand Up @@ -134,10 +135,11 @@ tipView.dismiss()
```
<a name="customising"> Customizing the appearance </a>
--------------
In order to customize the `EasyTipView` appearance and behavior, you can play with the `Preferences` structure which encapsulates all the customizable properties of the ``EasyTipView``. These preferences have been split into three structures:
In order to customize the `EasyTipView` appearance and behavior, you can play with the `Preferences` structure which encapsulates all the customizable properties of the ``EasyTipView``. These preferences have been split into four structures:
* ```Drawing``` - encapsulates customizable properties specifying how ```EastTipView``` will be drawn on screen.
* ```Positioning``` - encapsulates customizable properties specifying where ```EasyTipView``` will be drawn within its own bounds.
* ```Animating``` - encapsulates customizable properties specifying how ```EasyTipView``` will animate on and off screen.
* ```Highlighting``` - encapsulates customizable properties specifying if and how ```EasyTipView``` will show a highlighting overlay.

| `Drawing ` attribute | Description |
|----------|-------------|
Expand Down Expand Up @@ -177,6 +179,17 @@ In order to customize the `EasyTipView` appearance and behavior, you can play wi
|`dismissDuration`|Dismiss animation duration.|
|`dismissOnTap`|Prevents view from dismissing on tap if it is set to false. (Default value is true.)|

| `Highlighting ` attribute | Description |
|----------|-------------|
|`showsOverlay`| Wether or not to display a highlighting overlay. (Default value is false.) |
|`overlayColor`| The color of the highlighting background. |
|`circleColor`| The background color of the highlighting circle. |
|`circleMargin`| The margin of the highlighting circle to the corner of the view the tip view is attached to.This property only takes effect if `circleRadius` is nil. |
|`circleRadius`| The radius of the highlighting circle. If this property has a non-nil value the `circleMargin` property is ignored.|

<br><img src="https://raw.githubusercontent.com/KitchenStories/EasyTipView/feature/highlightingOverlay/assets/animation_highlight.gif" width="200">


<a name="customising-animations"> Customising the presentation or dismissal animations </a>
--------------

Expand Down
47 changes: 45 additions & 2 deletions Sources/EasyTipView/EasyTipView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ public extension EasyTipView {
transform = initialTransform
alpha = initialAlpha

if preferences.highlighting.showsOverlay {
overlay.viewToHighlight = view
superview.addSubview(overlay)
}

let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
addGestureRecognizer(tap)

Expand All @@ -174,8 +179,18 @@ public extension EasyTipView {
}

if animated {
UIView.animate(withDuration: preferences.animating.showDuration, delay: 0, usingSpringWithDamping: damping, initialSpringVelocity: velocity, options: [.curveEaseInOut], animations: animations, completion: nil)
}else{
UIView.animate(withDuration: preferences.animating.showDuration,
delay: 0,
usingSpringWithDamping: damping,
initialSpringVelocity: velocity,
options: [.curveEaseInOut],
animations: animations,
completion: nil)

UIView.animate(withDuration: preferences.animating.showDuration * 0.2) {
self.overlay.alpha = 1
}
} else {
animations()
}
}
Expand All @@ -199,6 +214,13 @@ public extension EasyTipView {
self.removeFromSuperview()
self.transform = CGAffineTransform.identity
}

UIView.animate(withDuration: preferences.animating.dismissDuration * 0.2) {
self.overlay.alpha = 0
} completion: { _ in
self.overlay.removeFromSuperview()
}

}
}

Expand Down Expand Up @@ -256,9 +278,18 @@ open class EasyTipView: UIView {
public var dismissOnTap = true
}

public struct Highlighting {
public var showsOverlay = false
public var overlayColor = UIColor.black.withAlphaComponent(0.7)
public var circleColor: UIColor? = nil
public var circleMargin = CGFloat(4)
public var circleRadius: CGFloat? = nil
}

public var drawing = Drawing()
public var positioning = Positioning()
public var animating = Animating()
public var highlighting = Highlighting()
public var hasBorder : Bool {
return drawing.borderWidth > 0 && drawing.borderColor != UIColor.clear
}
Expand Down Expand Up @@ -313,6 +344,17 @@ open class EasyTipView: UIView {
fileprivate(set) open var preferences: Preferences
private let content: Content

fileprivate lazy var overlay: TipViewHighlightingBackground = {
let background = TipViewHighlightingBackground(frame: UIScreen.main.bounds)
background.backgroundColor = preferences.highlighting.overlayColor
background.highlightingBackground = preferences.highlighting.circleColor
background.alpha = 0
background.circleRadius = preferences.highlighting.circleRadius
background.circleMargin = preferences.highlighting.circleMargin
background.tapAction = { [weak self] in self?.handleTap() }
return background
}()

// MARK: - Lazy variables -

fileprivate lazy var contentSize: CGSize = {
Expand Down Expand Up @@ -427,6 +469,7 @@ open class EasyTipView: UIView {
, presentingView != nil else { return }

UIView.animate(withDuration: 0.3) {
self.overlay.frame = UIScreen.main.bounds
self.arrange(withinSuperview: sview)
self.setNeedsDisplay()
}
Expand Down
Loading