Giter Club home page Giter Club logo

easytipview's Introduction

EasyTipView: fully customisable tooltip view written in Swift

Swift3 Platform Build Status Version Carthage Compatible License

Description

EasyTipView is a fully customizable tooltip view written in Swift that can be used as a call to action or informative tip.

Contents

  1. Features
  2. Installation
  3. Supported OS & SDK versions
  4. Usage
  5. Customizing the appearance
  6. Customising the presentation and dismissal animations
  7. License
  8. Contact
  • Can be shown pointing to any UIBarItem or UIView subclass.
  • Support for any arrow direction ←, →, ↑, ↓
  • Automatic orientation change adjustments.
  • Fully customizable appearance (custom content view or simply just text - including NSAttributedString - see the Example app).
  • Fully customizable presentation and dismissal animations.

CocoaPods

CocoaPods is a dependency manager for Cocoa projects.

CocoaPods 0.36 adds supports for Swift and embedded frameworks. You can install it with the following command:

$ gem install cocoapods

To integrate EasyTipView into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'EasyTipView', '~> 2.1'

Then, run the following command:

$ pod install

In case Xcode complains ("Cannot load underlying module for EasyTipView") go to Product and choose Clean (or simply press K).

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate EasyTipView into your Xcode project using Carthage, specify it in your Cartfile:

github "teodorpatras/EasyTipView"

Run carthage update to build the framework and drag the built EasyTipView.framework into your Xcode project.

Manually

If you prefer not to use either of the aforementioned dependency managers, you can integrate EasyTipView into your project manually.

  • Supported build target - iOS 8+ (Xcode 8)
  1. First you should customize the preferences:
var preferences = EasyTipView.Preferences()
preferences.drawing.font = UIFont(name: "Futura-Medium", size: 13)!
preferences.drawing.foregroundColor = UIColor.whiteColor()
preferences.drawing.backgroundColor = UIColor(hue:0.46, saturation:0.99, brightness:0.6, alpha:1)
preferences.drawing.arrowPosition = EasyTipView.ArrowPosition.top

/*
 * Optionally you can make these preferences global for all future EasyTipViews
 */
EasyTipView.globalPreferences = preferences
  1. Secondly call the show(animated: forView: withinSuperview: text: preferences: delegate:) method:
EasyTipView.show(forView: self.buttonB,
withinSuperview: self.navigationController?.view,
text: "Tip view inside the navigation controller's view. Tap to dismiss!",
preferences: preferences,
delegate: self)

Note that if you set the EasyTipView.globalPreferences, you can ommit the preferences parameter in all calls. Additionally, you can also ommit the withinSuperview parameter and the EasyTipView will be shown within the main application window.

Alternatively, if you want to dismiss the EasyTipView programmatically later on, you can use one of the instance methods:

let tipView = EasyTipView(text: "Some text", preferences: preferences)
tipView.show(forView: someView, withinSuperview: someSuperview)

// later on you can dismiss it
tipView.dismiss()

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:

  • 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.
Drawing attribute Description
cornerRadius The corner radius of the tip view bubble.
arrowHeight The height of the arrow positioned at the top or bottom of the bubble.
arrowWidth The width of the above mentioned arrow.
foregroundColor The text color.
backgroundColor The background color of the bubble.
arrowPosition The position of the arrow. This can be:
+ .top: on top of the bubble
+ .bottom: at the bottom of the bubble.
+ .left: on the left of the bubble
+ .right: on the right of the bubble
+ .any: use this option to let the EasyTipView automatically find the best arrow position.
If the passed in arrow cannot be applied due to layout restrictions, a different arrow position will be automatically assigned.
textAlignment The alignment of the text.
borderWidth Width of the optional border to be applied on the bubble.
borderColor Color of the optional border to be applied on the bubble. In order for the border to be applied, borderColor needs to be different that UIColor.clear and borderWidth > 0
font Font to be applied on the text.
shadowColor The color of the shadow (default UIColor.clearcolor).
shadowOpacity The opacity of the shadow (default 0). For the shadow to be drawn, both shadowColor and shadowOpacity must be set to a valid value.
shadowRadius The radius of the shadow (default 0).
shadowOffset The offset of the shadow.
Positioning attribute Description
bubbleHInset Horizontal bubble inset within its container.
bubbleVInset Vertical bubble inset within its container.
contentHInset Content horizontal inset within the bubble.
contentVInset Content vertical inset within the bubble.
maxWidth Max bubble width.
Animating attribute Description
dismissTransform CGAffineTransform specifying how the bubble will be dismissed.
showInitialTransform CGAffineTransform specifying the initial transform to be applied on the bubble before it is animated on screen.
showFinalTransform CGAffineTransform specifying how the bubble will be animated on screen.
springDamping Spring animation damping.
springVelocity Spring animation velocity.
showInitialAlpha Initial alpha to be applied on the tip view before it is animated on screen.
dismissFinalAlpha The alpha to be applied on the tip view when it is animating off screen.
showDuration Show animation duration.
dismissDuration Dismiss animation duration.
dismissOnTap Prevents view from dismissing on tap if it is set to false. (Default value is true.)

The default animations for showing or dismissing are scale up and down. If you want to change the default behavior, you need to change the attributes of the animating property within the preferences. An example could be:

preferences.animating.dismissTransform = CGAffineTransform(translationX: 0, y: -15)
preferences.animating.showInitialTransform = CGAffineTransform(translationX: 0, y: -15)
preferences.animating.showInitialAlpha = 0
preferences.animating.showDuration = 1.5
preferences.animating.dismissDuration = 1.5

This produces the following animations:

For more animations, checkout the example project. Once you configured the animations, a good idea would be to make these preferences global, for all future instances of EasyTipView by assigning it to EasyTipView.globalPreferences.

EasyTipView is developed by Teodor Patraş and is released under the MIT license. See the LICENSE file for details.

Logo was created using Bud Icons Launch graphic by Budi Tanrim from FlatIcon which is licensed under Creative Commons BY 3.0. Made with Logo Maker.

You can follow or drop me a line on my Twitter account. If you find any issues on the project, you can open a ticket. Pull requests are also welcome.

easytipview's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easytipview's Issues

For Obj-C

Hi there,

This library really look great. But not sure if it is possible for to use for Obj-C project?

Cause I've tried to "pod install" it to my Obj-C project, and realized that inside EasyTipView.h only have 2 methods and not able for us to set text for it.

Hoping you can spend some minutes to help on this, appreciate it much.

I need dismiss EasyTipView in a superView

What you think about this:

class func hideAllInSuperView(sview: UIView) {
    for subview in sview.subviews {
        if subview is EasyTipView {
            let sub = subview as! EasyTipView      

            UIView.animateWithDuration(0.2, animations: { () -> Void in
                sub.transform = CGAffineTransformMakeScale(0.3, 0.3)
                sub.alpha = 0
                }) { (finished) -> Void in
                    sub.removeFromSuperview()
            }
        }
    }
}

Support of Chinese characters

For some reason, the EasyTipView will not show Chinese characters in my code. It works for Japanese characters but not Chinese wording ... any thought on this?
EasyTipView(text: "觀看更多內容", preferences: preferences, delegate: self)

cornerRadius not drawn

After updating the code to swift3 so it would run in my project, I'm having a strange issue where it doesn't draw the final addArc rounded corner. It only does this when the arrow is on the right side. It's the final line of this function that does the drawing:

fileprivate func drawBubbleRightShape(_ frame: CGRect, cornerRadius: CGFloat, path: CGMutablePath) {

    path.addArc(tangent1End: CGPoint(x: frame.origin.x + frame.width, y: frame.origin.y), tangent2End: CGPoint(x: frame.origin.x, y: frame.origin.y), radius: cornerRadius)
    path.addArc(tangent1End: CGPoint(x: frame.origin.x, y: frame.origin.y), tangent2End: CGPoint(x: frame.origin.x, y: frame.origin.y + frame.height), radius: cornerRadius)
    path.addArc(tangent1End: CGPoint(x: frame.origin.x, y: frame.origin.y + frame.height), tangent2End: CGPoint(x: frame.origin.x + frame.width, y: frame.origin.y + frame.height), radius: cornerRadius)
    path.addArc(tangent1End: CGPoint(x: frame.origin.x + frame.width, y: frame.origin.y + frame.height), tangent2End: CGPoint(x: frame.origin.x + frame.width, y: frame.height), radius:cornerRadius)
}

For the life of me I can't see why it doesn't draw the rounded corner. Any ideas?

Wrong frame on portrait orientation

The issue only happens when the view controller open in portrait orientation, and after you make a little orientation changes the tip adjust to the right frame, is this something known ?

image

EasyTipView not showing in superview.

So, I have did this in my viewDidLoad:

EasyTipView.show(forView: self.shareBtnO,
                             withinSuperview: self.gradientView,
                             text: "Share",
                             preferences: tooltipPreferences ,
                             delegate: nil)

Preferences:

var tooltipPreferences = EasyTipView.Preferences()
        tooltipPreferences.drawing.font = UIFont(name: "FaktPro-Normal", size: 16)!
        tooltipPreferences.drawing.foregroundColor = UIColor.whiteColor()
        tooltipPreferences.drawing.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.1)
        tooltipPreferences.drawing.arrowPosition = EasyTipView.ArrowPosition.Top
        EasyTipView.globalPreferences = tooltipPreferences

but the the app crashes with error:
precondition failed: The supplied superview <<UIView: 0x16d8d670; frame = (0 0; 600 600); autoresize = W+H; layer = <CALayer: 0x16d8d730>>> is not a direct nor an indirect superview of the supplied reference view <<UIButton: 0x16e79ff0; frame = (-23 -15; 46 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x16e7a2e0>>>. The superview passed to this method should be a direct or an indirect superview of the reference view. To display the tooltip within the main window, ignore the superview parameter.: file /Users/perte/Documents/GitHub/project/Pods/EasyTipView/Source/EasyTipView.swift, line 94

I tried self.shareBtnO.superview instead of self.gradientView . I can't let that parameter empty because otherwise the tooltip appears under the my gradient view, like here
screen shot 2016-07-11 at 19 31 03

Unnecessary reimplementation of `convertRect`

In the arrange function the refViewFrame is calculated with an extension to UIView called originWithinDistantSuperView.

In iOS 8 there is native support for that functionality (https://developer.apple.com/reference/uikit/uiview/1622442-convert)

let refViewFrame = CGRect(origin: presentingView!.originWithinDistantSuperView(superview), size: presentingView!.frame.size)

can be replaced by

let refViewFrame = presentingView!.convertRect(presentingView!.bounds, toView: superview)

(in swift 3 it has changed name to just convert)

Programmatically created Navigation Items

I've programmatically created a right bar button item. When I run

    EasyTipView.showAnimated(true,
        forView: navigationItem.rightBarButtonItem,
        withinSuperview: self.navigationController?.view,
        text: "Tip view inside the navigation controller's view. Tap to dismiss!",
        preferences: preferences,
        delegate: self)

The error states I can't convert the UIBarButtonItem to UIView. Obviously if I had an IBOutlet it would work but I created this bar button item programmatically. How can I get this to work for my situation?

How to work with tableView cell

I tried to create tooltip inside tableview cell component, but... the position mess up after tableView is scrolled or reloaded..

is there any solution for this ?

Thank you in advance
Nice Library

Having trouble dismissing?

New to swift, so having trouble understanding how to dismiss the tooltip. I have it so when i click a button the tool tip displays, which it does. But will not dismiss. Thought to create a check variable for when the tool tip is displayed and the button is tapped again it is dismissed, but not working.

@IBAction func whyAction(sender: AnyObject) {
    let easy = EasyTipView(text: "Your privacy is respected per our Privacy Policy", preferences: EasyTipView.Preferences.init(), delegate: self)
    if tipViewStart == 0 {
        easy.showForView(sender as! UIView, withinSuperview: nil, animated: true)
        tipViewStart = 1
    } else {
        easy.dismissWithCompletion(nil)
        tipViewStart = 0
    }
  }

Just an update, didn't realize you had to click the tooltip to have it disappear... duh on my part. But nevertheless, can i dismiss by clicking on the button?

easyTipViewDidDismiss not called when calling dismiss()

I expected easyTipViewDidDismiss to be called when doing
self.tipView.dismiss()
but it isn't.

I do that when the user taps an overlay.
easyTipViewDidDismiss is called when the user taps the tipView (so the delegate should be correct).

Is it an issue or am I holding it wrong?

Auto dismiss option?

Is there a way to set a tipView duration? (something like an auto dismiss after a established period)
Thank you for your work.

Swift3.0 Support?

Hi
0.1.8 can not support Swift3.0
is there a Swift3.0 branch or tag

Thank you

If text is too short, arrow tip will be misplaced.

If the text contained in the tip view is too short, making the width of the tooltip too small compared to the width of the view target, the arrow tip will be displayed at far right.

To replicate the issue just give the C rectangle in the example a width of 80, and write inside the relative tooltip the word "Tip".

I'll also look into this in the next days if I have some free time.

Thank you!

Reference to the EasyTipView created

Is there a way to get the EasyTipView instance created with show method? E.g. to store it so later I can close them all if more than one on screen?

Cocoapod installs 1.0.2 instead of requested version (1.0.0)

I've tried to install 1.0.0 (or 1.0.1) version (one before Swift 3) but it is using 1.0.2 whatever version I will choose:

# Uncomment this line to define a global platform for your project
platform :ios, '9.0'

target 'EasyTipView-Example' do
  # Comment this line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for EasyTipView-Example
  pod 'EasyTipView', '~> 1.0.1'

end

and here is the terminal output:

Analyzing dependencies
Downloading dependencies
Using EasyTipView (1.0.2)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 1 total
pod installed.

Showing tip for UIView elements that are not visible on screen (not visible for user)

I have issues when showing tips for elements that are not visible on screen (view.window is nil)
Tips showed for current screen but not for uiview controls which are not visible for user.
When I scroll th screen, those tips are also scrolled up with screen. Is there some elegant solution for this problem, so I can put tips on proper position for those controls?

I tried to scroll up grammatically, and then show tips, but tips are still scrollable.

Error - Expressions are not allowed at the top level

Hi,

I just installed the lib but I'm always getting a few errors inside the lib.

The first error returned is "Expressions are not allowed at the top level" at line 151.

I've installed version 1.0.2 using cocoapods

Am I missing something?
captura de tela 2016-09-16 as 00 13 38

thanks,

Filipe

New version for Xcode 7.3

As Xcode 7.3 is released and _stdlib_getDemangledTypeName unresolved error is merged to master could you please create new version?

More control on positioning.

Currently we can display a tip view above another view (view A), with the tip view horizontally aligned with view A. Is it possible to specify offset? For example:

Center tip view, with 10px to the right;
Place the tip view on the right, with 20px to the left.

Thanks!

Dismiss EasyTipView when click outside

I have an app with navigationBar and tabBar. What I want is to dismiss EasyTipView when user clicks anywhere outside of the tip. How can it be implemented?

Swift 3 errors

I have Xcode 8 and trying to convert my project to Swift 3.

In my Podfile:
pod 'EasyTipView', '~> 1.0.2'

When I build the project, I get:

“Use Legacy Swift Language Version” (SWIFT_VERSION) is required to be configured correctly for targets which use Swift. Use the [Edit > Convert > To Current Swift Syntax…] menu to choose a Swift version or use the Build Settings editor to configure the build setting directly.

What am I doing wrong?

IBInspectable / IBDesignable support?

Any plans for adding IBInspectable / IBDesignable support so that it becomes a bit easy for use in storyboard? Also it would be a good idea to support encoding / decoding by subclassing NSCoder.

Support for Objective-C?

The EasyTipView/EasyTipView-Swift.h that is being compiled only supports:

@property (nonatomic, strong) UIColor * _Nullable backgroundColor;

- (void)showWithAnimated:(BOOL)animated forItem:(UIBarItem * _Nonnull)item withinSuperView:(UIView * _Nullable)superview;

- (void)showWithAnimated:(BOOL)animated forView:(UIView * _Nonnull)view withinSuperview:(UIView * _Nullable)superview;

- (void)dismissWithCompletion:(void (^ _Nullable)(void))completion;

It's impossible to even set the text or description of the tooltip..

[EasyTipView - Info] The arrow position you chose <Bottom> could not be applied. Instead, position <Top> has been applied! Please specify position <Any> if you want EasyTipView to choose a position for you.

Could not able to Display tipview at the bottom of textField

Following is my code instead of showing it in the bottom it will show it on top of textfield does there is anything wrong with my side ?

    guard let _ = whenDidYouStartTextField.text where whenDidYouStartTextField.text?.characters.count > 0 else {

            var pref2 =  EasyTipView.Preferences()
            pref2.drawing.font = UIFont(name: "Futura-Medium", size: 13)!
            pref2.drawing.foregroundColor = UIColor.whiteColor()
            pref2.drawing.backgroundColor = UIColor.redColor()
            pref2.drawing.arrowPosition = EasyTipView.ArrowPosition.Bottom

            let tipView = EasyTipView(text: "Please select when you start.", preferences: pref2)
            tipView.show(animated: true, forView: whenDidYouStartTextField, withinSuperview: self.tableView, autoDismissAfter: 3)
            return
}

Extension of EasytipView

//
//  EasyTipView+Extension.swift
//  ScalpCoach
//
//  Created by IndrajitSinh Rayjada on 09/08/16.
//  Copyright © 2016 Indrajit. All rights reserved.
//

import Foundation
import EasyTipView

extension EasyTipView {
    func show(animated animated: Bool = true, forView view: UIView, withinSuperview superview: UIView? = nil, autoDismissAfter: Double) {
        self.show(animated: animated, forView: view, withinSuperview: superview)
        let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(autoDismissAfter * Double(NSEC_PER_SEC)))
        dispatch_after(delayTime, dispatch_get_main_queue()) { [weak self] in
            self?.dismiss()
        }
    }
}

Returning the EasyTipView created by the class "show" functions

I have been using EasyTipView to implement a demo system within the app. It works well but I found that creating the tipview and then showing it caused dismissal to not trigger the onDismiss delegate. To get around this, I have used the class show functions. When the tip is dismissed, the delegate method is called, which is great. However, I then have no way to dismiss a tip using the dismiss function within my own code. To address this, I simply altered the code to return the EasyTipView from the class functions. It seems to work well. I will try to put a pull request in place to make the change available if you wish to include it.

Thanks for making the code available!

Geoff S

Does this work for Stackviews

I have a form with fields that are stack in a UIStackView. does this pod not capable to be use with stackView i tried this but does not work

var preferences = EasyTipView.Preferences()
            preferences.drawing.backgroundColor = UIColor(hue:0.58, saturation:0.1, brightness:1, alpha:1)
            preferences.drawing.foregroundColor = UIColor.darkGray
            preferences.drawing.textAlignment = NSTextAlignment.center
            
            preferences.animating.dismissTransform = CGAffineTransform(translationX: 100, y: 0)
            preferences.animating.showInitialTransform = CGAffineTransform(translationX: -100, y: 0)
            preferences.animating.showInitialAlpha = 0
            preferences.animating.showDuration = 1
            preferences.animating.dismissDuration = 1
            
            let view = EasyTipView(text: "Tip view within the green superview. Tap to dismiss.", preferences: preferences)
            view.show(forView: buttonA, withinSuperview: self.myStackView)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.