Code Monkey home page Code Monkey logo

zlswipeableviewswift's Introduction

ZLSwipeableViewSwift

A simple view for building card like interface like Tinder and Potluck. ZLSwipeableViewSwift is based on ZLSwipeableView.

Preview

Custom Animation

direction

Custom Swipe

direction

Custom Direction

direction

Undo

direction

Rewind

direction

CocoaPods

You can install ZLSwipeableViewSwift through CocoaPods adding the following to your Podfile:

pod 'ZLSwipeableViewSwift'
use_frameworks!

Then import it using:

import ZLSwipeableViewSwift

Carthage

You can install ZLSwipeableViewSwift through Carthage by adding github "zhxnlai/ZLSwipeableViewSwift" to your Cartfile

Swift Package Manager

You can install ZLSwipeableViewSwift through Swift Package Manager by adding it to the dependencies value of your Package.swift.

dependencies: [
    .package(url: "https://github.com/zhxnlai/ZLSwipeableViewSwift", .branchItem("master"))
]

Usage

Check out the demo app for an example. It contains the following demos: Default, Custom Animation, Custom Swipe, Allowed Direction, History, Previous View, Should Swipe and Always Swipe.

Instantiation

ZLSwipeableView can be added to storyboard or instantiated programmatically:

var swipeableView = ZLSwipeableView(frame: CGRect(x: 0, y: 0, width: 300, height: 500))
view.addSubview(swipeableView)

Adding Views

ZLSwipeableView supports both adding views to the front and to the back.

public var numberOfActiveView = UInt(4)
public var nextView: (() -> UIView?)?
public var previousView: (() -> UIView?)?

Adding views to the back

nextView, a closure that returns an UIView, works with loadViews and numberOfActiveView. It acts as the data source. After defining it, ZLSwipeableView will call loadViews which will invoke nextView numberOfActiveView times and insert them in the back. loadViews will also be called each time a view is swiped.

public func loadViews()
// Usage:
swipeableView.numberOfActiveView = 3
swipeableView.nextView = {
  return UIView()
}
swipeableView.loadViews() // optional, automatically call after nextView is set

Adding views to the front

previousView works with rewind, which inserts a view in the front and positions it at the center with animation. Note that rewind calls previousView only when history is empty, otherwise it returns the most recently swiped view. Please try out the Previous View example for more information.

public func rewind()
// Usage:
swipeableView.previousView = {
  return UIView()
}
swipeableView.rewind()

Interface Builder

If you need to work with Interface Builder, the demo app includes examples of both creating views programmatically and loading views from Xib files that use Auto Layout.

Removing Views

Swiping programmatically

The user can swipe views in the allowed directions. This can also happen programmatically.

You can swipe the top view programmatically in one of the predefined directions or with point and direction in the view's coordinate.

public func swipeTopView(inDirection direction: Direction)
// Usage:
swipeableView.swipeTopView(inDirection: .Left)
swipeableView.swipeTopView(inDirection: .Up)
swipeableView.swipeTopView(inDirection: .Right)
swipeableView.swipeTopView(inDirection: .Down)

public func swipeTopView(fromPoint location: CGPoint, inDirection directionVector: CGVector)
// Usage:
swipeableView.swipeTopView(fromPoint: CGPoint(x: 100, y: 30), inDirection: CGVector(dx: 100, dy: -800))

Rewinding

ZLSwipeableView keeps a history of swiped views. They can be retrieved by calling rewind.

public var history = [UIView]()
public var numberOfHistoryItem = UInt(10)

public func rewind()

Removing all views

To discard all views and reload programmatically (discarded views cannot by rewinded):

swipeableView.discardViews()
swipeableView.loadViews()

Delegate

Here is a list of callbacks you can listen to:

swipeableView.didStart = {view, location in
    print("Did start swiping view at location: \(location)")
}
swipeableView.swiping = {view, location, translation in
    print("Swiping at view location: \(location) translation: \(translation)")
}
swipeableView.didEnd = {view, location in
    print("Did end swiping view at location: \(location)")
}
swipeableView.didSwipe = {view, direction, vector in
    print("Did swipe view in direction: \(direction), vector: \(vector)")
}
swipeableView.didCancel = {view in
    print("Did cancel swiping view")
}

Customization

Here is a list of customizable behaviors:

public var animateView = ZLSwipeableView.defaultAnimateViewHandler()
public var interpretDirection = ZLSwipeableView.defaultInterpretDirectionHandler()
public var shouldSwipeView = ZLSwipeableView.defaultShouldSwipeViewHandler()
public var angle = CGFloat(1.0)
public var minTranslationInPercent = CGFloat(0.25)
public var minVelocityInPointPerSecond = CGFloat(750)
public var allowedDirection = Direction.Horizontal

interpretDirection

You can change how the direction gets interpreted by overriding the interpretDirection property. Take a look at the Custom Swipe example for details.

animateView

You can create custom animation by overriding the animateView property. Take a look at the Custom Animation example for details.

Should Swipe

shouldSwipeView, minTranslationInPercent and minVelocityInPointPerSecond determines whether a view should be swiped or not. Please see the Should Swipe example for details.

allowedDirection

The allowedDirection property limits the directions in which the user is allowed to swipe. Please see the Custom Direction example for details.

swipeableView.allowedDirection = .Left | .Up
swipeableView.allowedDirection = .All

angle

You can change the rotation of the swipe views with the 'angle' property

Misc

public func topView() -> UIView?

public func activeViews() -> [UIView]

Requirements

  • iOS 7 or higher.

Credits

Big thanks to the contributors of ZLSwipeableView.

License

ZLSwipeableViewSwift is available under MIT license. See the LICENSE file for more info.

zlswipeableviewswift's People

Contributors

algrid avatar andrewsb avatar antongolikov avatar benwu7 avatar cs-couture avatar dentelezhkin avatar domeniconicoli avatar eeshishko avatar jboulter11 avatar kennylugo avatar klep avatar krisanthony avatar lucas-gronlund avatar oaleeapp avatar sairamkotha avatar samukei avatar xxminamixx avatar yusayusa avatar zhxnlai avatar

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

zlswipeableviewswift's Issues

Init with frame initialiser is not visible for some reason

I just did installed ZLSwipeableViewSwift and when I tried to use it exactly as in an setup instructions, I noticed that `init(frame: CGRect) is not visible. It throws me an error.

ZLSwipeableView(frame: CGRectMake(0, 0, 300, 500))
Incorrect argument label in call (have 'frame:', expected 'coder:')

Can't form Range with end < start

Hi,
when I try to make rewind... I receive range error in loadViews()
Why in your example project not yet ?
I'm use Storyboard
thanks

No indexes?

Maybe I'm thinking about this the wrong way, but without indexes I'm having a hard time figuring out how to hook up a proper datasource.

Seems like I need to keep a manual count in nextView and constantly check if it's the last one to roll it back to zero?

Would be really nice to have .nextView { (index) in - but perhaps I'm not thinking about it the right way

Thanks!

Init with frame initialiser is not visible for some reason

I setup using cocoapods and did import ZLSwipeableViewSwift and when I tried to use it exactly as in an setup instructions, I noticed that init(frame: CGRect) is not visible. It throws me an error.

ZLSwipeableView(frame: CGRectMake(0, 0, 300, 500))
Incorrect argument label in call (have 'frame:', expected 'coder:')

I can see that class has

 override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
}

but not sure why it doesn't see it.

Sample shows swipeableView = ZLSwipeableView(), but GitHub setup shows
"var swipeableView = ZLSwipeableView(frame: CGRect(x: 0, y: 0, width: 300, height: 500)))"

swipeableView.numPrefetchedViews = 3 is deprecated, but is shown in how to setup this library here in Readme.

Update subview after layout

Hi,

I use this wonderful library to display cards which contained many informations.
In a card, there is a circle shape view ( cornerRadius = height /2 )
but it appears diamond shape.

To avoid that strange effect, I used to set that in a UIViewController :
override func viewDidLayoutSubviews() {
myView.layer.cornerRadius = myView.frame.size.width /2
}

How to do that in SwipeableView ?

I tried to set in nextCardView() :

    for i in 0..<swipeableView.activeViews().count {
        if let cardView = swipeableView.activeViews()[i] as? CardView {
            cardView.myView.layer.cornerRadius  = cardView.myView.frame.size.width / 2
        }
    }

it works but not in the last active view.

Thank you very much !

Determining swipe direction in Swiping delegate method

I'm close to the functionally I want, but just introduced a few bugs. I'm trying to handle horizontal and vertical swiping and do so in independent cases.

I'm very happy with the functionality on left and right swipes, but once vertical is introduced it breaks my setup. My current thought is to disable horizontal swiping completely and only allow the view to move vertically once a vertical swipe is triggered. I'm open to other thoughts though.

I'm also not sure how to completely disable horizontal swiping if I do go with that. and not allow the card to move on the x at all

screen shot 2016-08-17 at 9 56 17 am

screen shot 2016-08-17 at 9 56 17 am

How to return number of views like UITableview data source?

I am trying your sample, i cannot set number of views, i want to set only five view, which property i need to use before view is loading.
self.swipeableView.numberOfActiveView = 5;
self.swipeableView.discardViews()
self.swipeableView.loadViews()

i dont understand here

Getting started with adding cards

I'm only just getting started and couldn't get the cards to load on my main storyboard. I just think being a beginner, I'm having a difficulty getting off the ground. It was also interesting for me to learn that other pods like cartography also had to be installed to get the started. I assume it's probably a no brainer for seasoned programmers. But, I think as an amateur, it probably would be helpful to include in the getting started guideline to mention the pods that would be prerequisites.

Here's how my main viewcontroller looks like. I couldn't quite figure out how to get this working. I'm using this class as a reference to my main storyboard - https://gist.github.com/madman3/67ba7715f7a70854a1d03036bcc8feb3

Are there anymore details that would be required to help?

modify the animation

hi, I would like to ask you how to modify the rebound amplitude of cardView when it back to the primary position?

Swift 3 support

Hi guys, any date when u'll support swift 3 ?
Nice work by the way

didCancel and didEnd are not truly the final state

Hello,

I have added some custom transform to each card view, everything works fine except the cancel state. When I drag the top view and cancel it, it returns to stack and reset the transform that I added. I used the didCancel and didEnd method to add transform again but none of them work. It only work if I set transform again in didCancel (or didEnd) with a delay of 1-2 seconds.

So the question is how do I catch the final state of the view after Cancel ?

Thanks.

Exclude files in Pods directory

Hello Zhixuan, Thanks for your contribution.

I'm using Carthage with ZLSwipeableViewSwift and it's impossible to download the entire framework. The GFW is making everything slow as hell and I'm spending most of my time to download GIFs and Pods I don't want. Can you .gitignore them with a new commit? It'll optimize the entire download process who have weak internet connection like me.

Thank you again.

Undo doesn't work as expected

When using the UndoDemoViewController from example, the layer on top changes before insertTopView is called. So for example, if we have green, blue and red as the cards, and we swipe green, followed by hitting "undo", the top card changes to red. You can easily recreate this issue by reducing the number of cards to 3 so you can see the distinct colors.

Can't support Masonry?

When I use masonry to layout the content UI, the first card show prefect. Then I drag this first card, The content UI was messy. At the same time, I set frame to layout the content UI, it runs prefect. Did it not support Masonry?

Landscape

It's not working well in landscape. When roatating the device 3 cardviews will stay in portrait position meanwhile all others will position correctly

How can I more UI elements to view

Hi, I am trying to use this library but I can't manage to add labels and other UI elements to the swipeable View... does anyone has a demo project where it uses something similar?

thanks!

Merge Swift 2 branch

Seeing how Swift 2 has officially been released, it'd be nice for the branch to get merged into master.

PRs like #17 fixing issues from #15 should probably be merged or taken in regard as well.

Thanks 😁

Example app crash: Can't form Range with end < start

In History & Previous View implementations if I try to Rewind or Load Previous - the app crashes with "fatal error: Can't form Range with end < start". Don't need this functionality for now but can look into it myself a bit later when my schedule is less hectic

Xcode: Version 7.3
Device: iPhone 5s + any Simulator instance

如何获取当前卡片里的数值

我在nextCardView()里add了一个label,那么在swipeableView.didSwipe里面如何获得当前卡片的label的值。
我创建了一个全局变量,但是只能获得当前卡片后第四张卡片的label的Text

Unexpected behavior

I was testing your great library !
But, I noticed some strange behaviour :
When I was moving the the first card, I can move also all cards below it.
img_0832

I think you may set userIntereactionEnabled = true only for the first card..

View subviews nil during swiping callback

Hi,

Firstly thanks for the wonderful library.

I implemented the SwipeableView to replicate the tinder-like cards loading from xib. I want to implement the feature where on swiping left a label appears on top right of the card view that says something like "swiping left".

To do this I created the view and added the "swiping left" label in xib with alpha zero. I'm trying to change alpha property of the subview of CardView during the swipe callback.

swipeableView.swiping = { view, location, translation in
    let thisView = view as! CardView
    let transPercentage = translation.x / 200
    thisView.joinView.alpha = abs(transPercentage)
}

The above code crashes at the line where I try to set the alpha property with error fatal error: unexpectedly found nil while unwrapping an Optional value. On inspecting I find that thisView.joinView is nil.

On the contrary, If i set thisView.alpha = ... it works fine as thisView is found to be the correct instance of CardView.

It seems that all the subviews of thisView are nil which is unexpected as the view has already been initialized and is visible.

How can I get a non-nil reference to my custom view subviews so that I can change their properties during swipe callback?

Thanks!

Showing a form on each swipe view [Duplicate]

As per demo we can swipe through the cards but what if we want to hold a customize UI on each swipe view such as a form with textfields and button, in that case probably we need to add respective child view controller to handle button action. Any best practices to accomplish the stated requirement?

How to make swipes always look programmatic?

Basically, I want to disable the anchoring to the touch point and also disable vertical movement (I already have the allowed directions set to horizontal) so that the swipes always look like the programmatic calls. I only have an interest in left & right swipes. How would one go about this? I'm fine if you point me in the general direction for where to go about this as i'm sure it will require some customization on my end. Thanks.

How can I add a swipe hint?

I'm using the the class in my on boarding.
I'd like to add a delicate card move to hint the user that the view is he's currently seeing is swipeable.

Anyone has an idea how can I achieve this?
I'd like the change to appear "real", as if someone really did a little swipe to the right, and then removed his finger.

Method 'rewind()' breaks auto layout

Trying to implement the rewind function, and it brings back the last view, however, it seems to break auto layout constraints on that previous view and all subsequent previous view attempts.

I tried just using 'rewind()' with no additional features and also tried refactoring 'nextView' method for use with 'previousView' method and still get same results:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    swipeableView.nextView = {
        return self.nextCardView()
    }

    swipeableView.previousView = {
        return self.previousCardView()
    }
}

func nextCardView() -> UIView? {
    if currentIndex >= items.count {
        currentIndex = 0
    }

    let cardView = NSBundle.mainBundle().loadNibNamed("CardView", owner: self, options: nil)[0] as! CardView
    swipeableView.addSubviewWithFullConstraints(cardView)

    cardView.loadWithItem(items[currentIndex])
    currentIndex++

    return cardView
}

func previousCardView() -> UIView? {
    if currentIndex == 0 {
        return nil
    }

    currentIndex--

    let cardView = NSBundle.mainBundle().loadNibNamed("CardView", owner: self, options: nil)[0] as! CardView
    swipeableView.constrainSubviewWithFullConstraints(cardView)

    cardView.loadWithItem(items[currentIndex])

    return cardView
}

iPad slow animation

If your call swipeTopView(inDirection direction: Direction) the animation on iPad is very slow. Sometimes the duration is up to 5 seconds, depending on iPad model.

We are using swift 2.2 with iOS9

Showing a form on each swipe view

As per demo we can swipe through the cards but what if we want to hold a customize UI on each swipe view such as a form with textfields and button, in that case probably we need to add respective child view controller to handle button action. Any best practices to accomplish the stated requirement?

swiping distorts imageview (which is a subview of swipeable view)

in my card view.swift file i'm adding an image view to fit the bounds of the swipeable view. this looks normal at first. however when i start dragging the swipeable view, the image becomes much larger.

this is more of an issue with how I'm using the cartography pod, but since you guys used it in the original library. I thought you guys could help me diagnose the issue.

i tried using the following thinking that it was gonna be very straightforward, but i don't know what to do anymore. The constraints don't seem to respect the card bounds when it starts being translated and rotated.

Any advise please?

    constrain(imageView, self) { obj1, obj2 in
        obj1.width == obj2.width
        obj1.height == obj2.height
        obj1.left == obj2.left
        obj1.right == obj2.right
        obj1.bottom == obj2.bottom
        obj1.top == obj2.top
    }

How to Manage z-index

How to manage z-index to add new cards on top,
I try rewind but is not what I'm looking for because you need to swipe a card to get same card on top.

Adding a tap gesture

Hi,
I am trying to add a tap gesture recognizer to the swipeableView. How can I do that properly ?
Thanks !

Adding swiped view back to the stack of views

I want to achieve something like this:

  1. User swipes the top most view, either towards left or right
  2. The swiped view is added to the bottom of view stack
  3. So say if there were three views then first view is re-visible after third swipe

Is it something which can be achieved out of the box or does it need customization in existing code base? Any code pointers shall be helpful.

Thanks in advance.

didEnd return not last view

Hi,
didEnd and didCancel returned not the last view

Can you solve this problem or help me please? :-)

thanks in advance

How do you determine whether the user swiped left or right?

didSwipe returns .Horizontal as direction when swiping left and right. How do you determine whether it was a swipe left or swipe right? Kinda pointless to just return .Horizontal since developers would want to do something for each direction.

Indexing support as in UITableView

Hi,

It's a great library but I don't know how to maintain indexes. I thought of tagging views but that's just a workaround.
Can we have some callback like viewForCardAtIndex: for next as well as previous cards?

Can't get Custom Direction to work. Help?

Hi there,

I want the cards to only be swippable left and right. I tried this:

swipeableView.allowedDirection = .Left | .Right but I am getting the following error in XCode 7.2.1:

ZLSwipeableViewController.swift:111:62: Binary operator '|' cannot be applied to two 'Direction' operands

What am I doing wrong?

Thanks

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.