Horizontal UIScrollView and multiple thumbnail images in iOS? - ios

I need to create a horizontal UIScrollView which to hold hundreds of thumbnail images, just like a slide of thumbnails and a UIImageView that will hold the center image of UIScrollView
For example, there will be 6 thumbnails showing in a single screen, each of them are horizontally adjacent to each other.
My problem is that I don't know how to make a horizontal UIScrollView to hold the multiple thumbnails which showing at the same time and then display the center image to the Topview image?
A sample photo is as below. See the bottom part of the screen.
Screenshot Image

There are many ways, here is one:
The top part
Option 1.1
The top image views can be handled by a UIPageViewController wrapping something to the effect of ImageDetailViewController
Option 1.2
The top is a UICollectionViewController and the large top images are UICollectionViewCells. You can use UICollectionViewFlowLayout with a horizontal scroll direction and pagination true.
The bottom part
Option 2.1
The bottom part should be a UICollectionViewController as you may need to overflow off the screen and it is fast and scrolls horizontally.
Option 2.2
The bottom part can be a StackView created with items programmatically and filled in with a spacing you want. Add a UIGestureRecognizer to detect touch down.
Recommendation
Top: 1.1 - Use a UIPageViewController
Bottom 2.2 - Use a stacked view with a gesture recogniser over the top
Assuming you want them to pan over the bottom, I would say 2.2 is the option, but slightly harder.
So what this looks like is a UIPageViewController, with a floating thumbnail on the bottom to scrub.You can just implement a simple ImageViewer (UIImageView inside a UIScrollView to allow zooming etc).
This will give left/right scroll for free.
You will layout the thumbnails on the bottom inside a stack view and it is better to handle one giant gesture recogniser on the bottom so you can keep it continuous without lifting finger. You will just have to get the coordinates or view that is translated inside the touch.
Rather than go into code because there will be a few different classes I will try to give a topographic explanation.

Related

Floating content of UIScrollView when smaller

I'm trying to make kind of collage, so I want to resize image and drag it to any position of scroll view. Currently I can drag image only when it is bigger than scroll view. But when it is smaller than it sticks to top left corner. Yes, I can use scrollViewDidZoom to move image to center for example, but it is not what I'm looking for. For example I want to allow users to drag an image to any position of the scroll view, like this
To do that I just merge big empty image with my image I want to move. Looks like a bad solution, but it working as I wanted

Layout for 3 uiImageView side by side using swift

I want to create a control for ios 8+ where we have 3 images. In center image in big and left/right images are small.
I have to create some code in swift, using Stack Layout but it will not work in iOS 8 as it is available from ios 9. So need to change this. What should i use to keep images together (left and right bottom)?
Also another problem i have is, i need pan gesture on only big center image not on the small left and right image. So when i touch the big image i can move all three around the screen. Currently it if i touch any of 3 all moves.
Functions:
small left/right image: Act as button for running a swift function
middle image: on pan gesture drag all three around screen
You have 3 choices to create an image slider according to your requirement.
Using Scroll view (UIScrollView)
Using Collection view (UICollectionView)
Using Page Controller
Here are simple/basic logic, how and what you should use to achieve sliding image.
Using Scroll view (UIScrollView)
Add three images in scroll view with equal width
Set Height of middle image, according to your requirement (bigger than other)
Set width of any one image (probably middle) equal or around equivalent percentage (80% equal) to device screen using AutoLayout constraint.
Scroll view automatically scroll horizontally according to horizontal content size. You don't need to add Pan gesture.
You can also enable paging of scroll view.
Using Collection view (UICollectionView)
Add collection view with three (static) cells or single dynamic (You need to choose how do you want to update this feature in future. If you choose single dynamic cell then you can easily add more images in slider by adding its data into datasource variable, in future.)
Enable horizontal scroll only in collection view.
Update (make it bigger) Image height in data source method using index path for item (indexPath.item == 1).
Collection view have pan gesture also. You don't need to implement it.
You can enable pagination also.
Note: Set image/cell width equal to device screen or equivalent.
Using Page Controller
Here are nice reference tutorials, "How to use Page View Controller"
How To Create UIPageViewController Using Storyboard
How to Use UIPageViewController to Build Tutorial Screens
I do not recommend this option (Page view controller) but you have provided complete details about scope of your requirement (view controller level or it is simple child view slider), so this is an option to image slider also.

Custom Page Control with Paging Scrollview

Instead of the standard dots that Apple provides for a page control, I want to have something like this. However I don't want it to be in an infinite loop were you can circle around. All I care about is the scrollable text on top, not the parallax image.
Currently I have a paging scrollview that contains three view controllers so my custom page control will have only three words: Main, Today, Settings.
The way I see this being built is the following:
Subclass UIView and insert three UIButton's and evenly space them. The title of the buttons will be Main, Today, Settings.
Insert this UIView as child of scrollview (or maybe not)
Make UIView the width of the iPhone screen
Not sure about here now -> as you scroll the scrollview shift the UIView on and off the screen so that the UIButton will be centered in one of the view controllers in the scrollview.
Am I on right track or does anyone have a demo to this?
Yes. You are on right track. You can use scrollView for this exact purpose. You have to make use of scrollViewDelegate methods for this. The below link will explain you how to do that.
How to make Paging with scrollView.

Using parallax scrolling for a UIImageView

I am looking to create a simple parallax scrolling effect on an image view that is embedded in a UIScrollView in swift (actually, I have the image embedded in a view that is, in turn, embedded in the UIScrollview). This is the layout I am working with:
As you can see from the screenshot above, the image is larger than the UIImageView to which it is assigned. When the user scrolls down the screen I would like other (vertical) portions of the image to become visible, such as in the example given in this tutorial. The tutorial, however, uses a collection view to display a mutable array of images and I could not figure out how to adapt it to my purposes. Does anyone have an idea as to how to accomplish this?

Triple Nested UIScrollView paging issue

Backstory
I have an iPad app that needs to allow the user to navigate through groups of images. Each group is laid out in its own vertical UIScrollView (paged) so the user can swipe up and down down to see each image. Each of the group UIScrollViews is placed in a single (only one exists in the app) outer horizontal UIScrollView (also paged). This works great.... I can swipe up and down to view the images in a group and swipe left and right to go to the next or previous group.
Problem
The problem started when I needed to add zooming for each image. I accomplished this by placing each image inside its own UIScrollView. When the image is zoomed I can pan around the image and when I get to the top or the bottom of the zoomed image the group's vertical UIScrollView pages to the next or previous image as expected. Unfortunately the outer horizontal scrollview will not page to the next group when the image is zoomed and I pan to the leftmost or rightmost edge.
Is there a better(more correct) approach than triple nesting UIScrollViews or can I somehow forward touches to the outer horizontal scrollview?
Any help or suggestions would be greatly appreciated.
hope i'm not too late but I think I have a solution for your problem.
Here you can find an Xcode project demonstrating the scrollview setup you have, your problem and the proposed solution: https://bitbucket.org/reydan/threescrollviews
Basically the solution was to add 1 pixel to the contentSize.width of the vertical scrollviews. This forces the vertical scrollview to scroll a little when you pan to the edge of the zoomed image. It scrolls a little and then continues to the next vertical scrollview.
If you download the project you will see that I've created some scrollviews in the viewDidLoad method. There, I create one horizontal scrollview containing 3 vertical scrollviews, each containing 5 images. Each image is actually incapsulated in a scrollview to enable per-image zooming. In total... triple nested scrollviews.
I've also left some colored borders so that I can easily see how each scrollview scrolls.
the magenta = horizontal scrollview
the white = vertical scrollview
the blue = the image scrollview (the one that contains the image and allows for zooming)
the red = the UIImageView
You will see that I've tagged each image scrollview with value 10. This is used in the implementation of - (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView delegate method where I return nil unless the event came from one of the image scrollviews.
If you have any questions about the project I made feel free to ask.
In the end, I would like to say that this browsing method is a little quirky for me as I sometimes scroll in the unwanted direction. Often I think I flick my finger vertically only to find the scrollview going left or right because it interpreted some tiny horizontal movement I had.
The problem I found with paging enabled for both horizontal and vertical movement is that the scrollviews are direction-locked, or so it seemed to me.
EDIT:
Today I've investigated the problem even more. These are my conclusions:
it's not a problem with zooming, it's a problem with having larger content in the innermost scrollview than the visible area(you can try this by zooming or simply initializing the content size larger than the bounds). This enables panning inside the inner-most scrollview and completely changes the behaviour of the touch events.
the bounce for a scrollview flag affects the behaviour of the panning(dragging) gesture when it reaches the edges of the content. If bounces=false then your panning gesture will stop at the edge, not forwarding the drag event up the chain (and thus not scrolling the parent scrollviews to show you other images). If bounces=true then, when you reach the edge and continue to drag the events will be forwarded to the parent scrollview and that scrollview will also be dragged. However, I've found that the dragging while bouncing reduces the distance dragged by aproximately 50%. This also happens in the Photos app.
if you start the dragging while the innermost scrollview is at the edge of the content then the scrollview is smart and will forward all events to the parent scrollview.
for some reason, triple nested scrollviews are problematic as the events are simply not forwarded between the topmost and middle scrollviews while panning inside the innermost scrollview. I have no idea why.
My solution with that +1 pixel to the content size, partially solves the problem.
EDIT 2013
Boy, these scrollviews are something out of this world :(
After more than a year of searching (just kidding... it was actually 2 days) I think I found a good elegant solution to the triple nested scrollviews.
I created a test project here:
https://github.com/reydanro/TripleNestedScrollViews
Inside the app, there is a switch which you can use to test with/without the fix.
The setup I am using in my app is a little different than this question. I have 1 vertical paged scrollview. Inside it, I have multiple horizontal paged scrollviews.
Inside some of the horizontal scrollviews I have another vertical paged scrollview.
Without the fix, once you get to the page with the inner-most scrollview you are pretty much stuck there as the vertical scrolling gestures are not forwarded to the outer-most scroll.
The fix is a custom UIGestureRecognizer that you need to add to the inner-most scrollviews. This recognizer follows touch events and if it detects a drag beyond the contentArea, then it will temporarily disable the rest of the scrollview's recognizers. This is the only method I discovered to make the scrollview forward the events up the chain
The gesture recognizer code is very rough with limited customization but should get the job done. At the moment I am focused on the app I develop, but will continue to update the repository.
PS: I haven't tested what happens with zoom but I see no reason why this method should not work (or be adapted to work).

Resources