Git Product home page Git Product logo

hstack-snap-to-scroll's Introduction

SnapToScroll

Drop-in SwiftUI-based container view for horizontal snapping.

To see the rest of the SwiftUI Library, visit our website.

example-video.mp4

Getting Started

Using SnapToScroll is straightforward. There's just three steps.

  1. Import SnapToScroll
  2. Replace HStack with HStackSnap
  3. Add .snapAlignmentHelper to your view.

An example:

import SnapToScroll                               // Step 1
...

HStackSnap(alignment: .center(32)) {              // Step 2

    ForEach(myModels) { viewModel in

        MyView(
            selectedIndex: $selectedIndex,
            viewModel: viewModel
         )
         .snapAlignmentHelper(id: viewModel.id)   // Step 3
     }
}                  

For more examples, see SnapToScrollDemo/ContentView.swift.

Configuration

HStackSnap comes with two customizable properties:

  • alignment: The way you'd like your elements to be arranged.
    • leading(CGFloat): Aligns your child views to the leading edge of HStackSnap. This configuration supports elements of various sizes, so long as they don't take up all available horizontal space (which would extend beyond the screen). Use the value to set the size of the left offset.
    • center(CGFloat): Automatically aligns your child view to the center of the screen, using the offset value you've provided. This is accomplished with inside of the .snapAlignmentHelper which sets the frame width based on the available space. Note that setting your own width elsewhere may produce unexpected layouts.
  • coordinateSpace: Option to set custom name for the coordinate space, in the case you're using multiple HStackSnaps of various sizes. If you use this, set the same value in .snapAlignmentHelper.

.snapAlignmentHelper comes with two options as well:

  • id: Required. A unique ID for the element.
  • coordinateSpace: Same as above.

Limitations

  • HStackSnap is currently designed to work with static content.

How it Works

At render, HStackSnap reads the frame data of each child element and calculates the scrollOffset each element should use. Then, on DragGesture.onEnded, the nearest snap location is calculated, and the scroll offset is set to this point.

Read through HStackSnap.swift and Views/HStackSnapCore.swift for more details.

Credits

Thanks to pixeltrue for the illustrations used in example 2.

hstack-snap-to-scroll's People

Contributors

flxfischer avatar rocxteady avatar trentguillory avatar ulazdins avatar zmetser 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

hstack-snap-to-scroll's Issues

It is not working on orientation change.

If you change orientation to landscape, HStackSnap not working as expected. I think there is a problem because the width of the stack is changed. Is there any solution for this?

HStackSnap(alignment: .leading(20)) {
  ForEachWithIndex(elements: self.dayStore.days) { index, day in
      GeometryReader { cardGeo in
          VStack {
              Text("cao \(index)")
          }
          .frame(maxWidth: .infinity)
          .frame(maxHeight: .infinity)
          .background(RoundedCorners(color: Color("Neutral White"), tl: 20, tr: 20, bl: 20, br: 20))
          .rotation3DEffect(Angle(degrees: (Double(cardGeo.frame(in: .global).minX))) / -30, axis: (x: 0, y: 10.0, z: 0))
          .snapAlignmentHelper(id: day.id)
      }
      .frame(width: abs(geo.size.width - 80))
      .frame(maxHeight: .infinity)
  }
}
.padding(.top, 10)
.padding(.bottom, 10)

HStack alignment

Is there a way to align all the items to the top.
Normally HStack alignment is used to align the items inside to the desired position.
For HStackSnap it is used for where it should snap.

I'm trying to recreate what you have in example 2 but with 3 items above each other. My search result doesn't always give me a multiple of 3 since sometimes there are only 8 results. when this happens the last 2 are aligned in the middle

Slider in View causes HStack to move also

I have a Slider in the View and when I move the slider, the View in the HStack also moves in the direction that I have moved the slider. Is there anyway to disable the gesture action in this lib while the Slider is moving?

Let me know if any more information is required

stuck in the center issue

Hi there,

I found an issue, if you scroll it fast in the beginning, it will stuck in the center sometimes.

I know this is because of ScrollView. When you trigger the ScrollView's scrolling, the Views which are inside the ScrollView, cannot get the DragGesture anymore. But before that, they have already started part of the scrolling, so they cannot finish it. If you use other Containers, like LIst (it also has a similar vertical scrolling behavior), there's no problem like this. Do you have any idea about this?

You could have a look at the effect here.
https://jmp.sh/SdccqRX

Thanks.

Does not work when nested in a `NavigationView`

Hello! I'm noticing an issue where the library doesn't work when nested in a NavigationView. The views are displayed correctly, however I am unable to scroll only when nested in a NavigationView. I have included a very simple implementation reusing your demo to show what is happening.
card test.zip

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.