iOS (iPhone only): Horizontal page scroll, where the scrolling page doesn't take up the whole screen - ios

I am trying to achieve horizontal page scrolling effect (partial view, not of the entire screen scrolling), like in the HGPageScrollView component.
I am a fairly novice iOS programmer, and I am having difficulty finding the parts of the code which provide just the horizontal scrolling with the swipe gesture. So I am looking for any help, either some sample code, or pointers to the code in the HGPageScrollView, which provide just the horizontal scrolling functionality (i.e. not even the UIPageControl dots at the bottom, just the vanilla scroll).
I am only looking for an implementation which works in iPhone landscape orientation, if that makes it any easier.
Why I am not using HGPageScrollView:
It is not ARC compliant.
It does way more than I need it to, I am just looking for the scrolling.
Consequently, it is proving quite difficult for me to find where to remove all the features I do not need, like clicking on page to change the scrolling mode to full screen (HGPageScrollViewModePage)
I would like to use this as an incentive to learn more about the components available in cocoa-touch, and roll my own implementation.
I think this question might be suggesting the solution, but I do not know how to implement it. I guess I don't fully understand it, as there aren't enough details for my novice skills to go on.

Use a UICollectionView and set the pagingEnabled property to YES.
If you want to do complex layouts of the items (like in your example above where items are split on both sides of the screen) you may want to provide your on UICollectionViewLayout: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionViewLayout_class/Reference/Reference.html#//apple_ref/occ/cl/UICollectionViewLayout

Related

How do you make a vertical text UILabel and UITextView for iOS in Swift?

If you came to this question based on the title but are not interested in Mongolian, you might be looking for this Q&A instead:
Swift: How can you rotate text for UIButton and UILabel?
I've been learning Swift in order to develop iOS apps for traditional Mongolian. The problem is that traditional Mongolian is written vertically from top to bottom and from left to right. My question is how do I display text vertically and still have line wrapping work?
If you stay with me for a minute, I'll try to explain the problem more clearly. Below is an image of the kind of text view I would like to achieve. In case the foreign script throws you off, I have included English text that follows the same pattern. In fact, if the app has any English text to display, this is how it should look.
For a simple one-line UILabel, a 90 degree clockwise rotation would work. However, for a multi-line UITextView I need to deal with line wrapping. If I just do a plain 90 degree rotation, the first thing written will end up being on the last line.
So far I have made a plan that I think can overcome this problem:
Make a custom font in which all of the letters are mirrored vertically.
Rotate the text view 90 degrees clockwise.
Mirror the text view horizontally.
That should take care of the text wrap.
I can do the mirrored font. However, I don't know how to do the Swift coding for the rotation and mirroring of the UITextView. I've found the following links that seem to give hints to parts of the solution, but they are all in Objective C and not in Swift.
How to rotate sub-views around their own centres?
Rotate UIView around its center keeping its size
iOS: Mirror content on screen
Mirroring UIView
There are traditional Mongolian apps in the app store (like this and this) but I haven't found anyone yet who is sharing their source code, so I don't know what they are doing behind the scenes to display the text. I plan to make my code open source so that it is not so hard for others in the future to develop apps for the several million people who read traditional Mongolian. Any assistance you can give to this endeavor would be much appreciated, not just by me but also by the Mongolian people. Even if you don't know yourself, upvoting this question to make it more visible would help.
Update
#sangonz's answer is still a great answer, but I temporarily unmarked it as the accepted answer because I just couldn't get everything to work. Specifically:
Enabling scrolling (either by embeding the custom view in a scrollview or by subclassing UIScrollView). In the github project, #sangonz said this should be easy, but it wasn't for me.
Getting a relayout (rather than stretching) of the word lines on an orientation change. I think this shouldn't be too hard to solve with a little more research.
Why don't the text lines go all the way to the edge of the view? There is a big gap at the bottom.
How to unlink the NSTextStorage of the custom vertical view from the other UITextView. (see this question)
Up to this point I have been using the original method I proposed above, but what I really want is to get something like what #sangonz proposed working.
I am also now considering alternate methods like
Using Core Text, Disadvantage: it feels like reinventing the wheel
Using WebKit, Disadvantage: Apple no longer uses WebKit for their UITextView
Edit: This is how I finally did it.
Here's a very basic implementation in my GitHub: Vertical-Text-iOS.
Nothing fancy, but it works. Finally I had to mix TextKit and image processing. Take a look at the code. It involves:
Subclassing NSTextContainer to get the right text dimensions.
Creating a custom UIView to render the text applying affine transformations to each line and rendering using NSLayoutManager to keep all TextKit features.
TextKit way
The proper way to keep all native text benefits (e.g. highlighting, selection...) is to use standard TextKit APIs. The method you are proposing would break all that or would possibly result in strange behaviour.
However, looks like TextKit in iOS does not support vertical orientation out-of-the-box yet, but it is prepared for that. As a side note, in OS X it is somewhat supported and you could call textView.setLayoutOrientation(.Vertical), but it still has some limitations.
The NSTextLayoutOrientationProvider protocol defines an interface
providing the default orientation for text laid out in a conforming
object, in absence of an explicit NSVerticalGlyphFormAttributeName
attribute. The only UIKit class that implements this interface is
NSTextContainer, whose default implementation returns
NSTextLayoutOrientationHorizontal. An NSTextContainer subclass that
handles vertical text could set this property to
NSTextLayoutOrientationVertical to support the custom layout
orientation logic.
Source: UIKit > NSTextLayoutOrientationProvider Protocol Reference for iOS
In conclusion, you should start subclassing NSTextContainer, and you will have to deal with NSLayoutManager and NSTextContainer a lot.
Custom image processing way
If, on the other hand you decide to follow your custom text rendering I suggest the following approach.
Render the normal text to a hidden layer with a normal font. Give it the correct size to its bounding box.
Get the text properties, mainly text height and line spacing.
Process the image drawing each line in reverse order from bottom to top as you can see in the image below. You should get a new CGImage as a result.
Rotate the image creating a UIImage and setting the correct UIImageOrientation value.
Insert that image into a UIScrollView that only allows horizontal scrolling.
Beware this method renders the whole text, so don't use it for very long texts. If you need to do that, you will need to consider a tiling approach. Watch WWDC 2013 > 217 - Exploring Scroll Views on iOS 7.
Good luck!
Update: (image from github project)
If you're going to rotate the text I would suggest using a right-to-left layout so that you can skip the mirroring step (and just rotate the other way).
You should be able to just set the label/textview's transform property:
view.transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(CGFloat(-M_PI_2)), view.bounds.width, view.bounds.height)
You need to translate after you rotate because the view rotates around its origin (in the upper left).
The good news is that gestures and taps are transformed at the same time the pixels are, so controls continue to work the way you expect them to.

Make UIScrollView scroll from scrolling inside OR outside of it

Say I have a UIScrollView that scrolls horizontally just fine. It's height is around 50px. After usability testing, a lot of people are trying to scroll the contents by panning outside of it. Here is the setup:
Where it says "Amount" is the scrollview
I am wondering if it is possible to attach a UIPanGestureRecognizer on the blurred background it sits on top of and have it scroll along with that as well. If this is possible, could someone give me a start on what that approach would possibly look like?
Nah, the simple solution is simply make the scroll view bigger .. it's just that simple.
Have it mostly transparent, with your content sitting where you want it.
What you describe in your question is a good idea but it's extremely! hard to really implement well, a total pain. You simply "make the scroll view bigger".
Nice looking app.
These may be relevant to you...
The UICollectionView "swipe-away" in iOS7 app manager?
Show/hide UIToolbar, "match finger movement", precisely as in for example iOS7 Safari

UITableView vs UIScrollView

I am working on an animation application. I would like to have an horizontal UITableView or horizontal UIScrollView that will show little images representing a drawing at page X.
Since that my animation app can easily have 200 drawings, this means that my UITableView or UIScrollView can contain 200 images.
Finally, I would like to implement UIAnimation, where the user will be able to reorder the images by drag and dropping. I would like to have something smooth...
I have 2 questions :
Which classes is the better for memory management? I think I understood UITableView automaticly unload cells that are off screen, not UIScrollView. Is that true?
Which one might be easier to implement, considering possible heavy load? (I found this for horizontal UITableView : EasyTableView
Thank you
You should look into tiling with UIScrollView. There have been some very good sessions talking about advanced use of UIScrollView at WWDC over the past three years, and the videos of those sessions are available if you're a registered developer. They'll show you how to use UIScrollView's tiling feature to load just the content that you need, much as UITableView loads only the content that it needs.
As far as I'm aware, UITableView doesn't work in a horizontal mode, so UIScrollView is currently your only choice if you're only considering classes in Cocoa Touch. I'm sure there are some third party options, but I don't know enough to recommend one.

Fluid full screen view transitions on iOS

I have a simple app that has a set of coloured views, one red, one green and one blue.
I am trying to make it so that when a swipe gesture is made the current view will switch to the next one in the list in a fluid manner, it looks like moving a long piece of paper with different colours on it.
Is there a way to do this (CoreAnimation)?
You could first look into UIScrollView. It seems to me that what you are trying to accomplish is the same you have, say, in Mobile Safari on an iPhone, when you show all your current pages and can go from one to the next by scrolling. This tutorial is particularly close to what you describe.
If you are looking into more advanced kind of transformations, than Core Animation would be the option.
Actually, nothing prevents using both approaches, UIScrollView to handle the swipe, Core Animation to add more animation to the pack...
You could use a UIScrollView to accomplish this. Add all of your colored views as subviews to the scroll view. Make sure your contentSize is setup appropriately and optionally setup paging to make the scrolling always snap to a certain border. See the scroll view programming guide for more info Scroll View Programming Guide

What's the technique to do expand/compact stack on iPad like Reeder and Photos?

On iPad, both the native Photos app as well as Reeder use a "expand/collapse stack" technique. Initially there is a stack of items on top of one another, each angled a bit with different corners showing. When you interact with them, the stack expands into a full screen and the items are laid out in a grid. When you collapse them, they collapse back into a stack.
What's the best way to set up my views to do the same thing? Should I just have a bunch of UIviews (one for each item) and manipulate their coordinates/transforms with an animation, or is there something more to it? Any example apps with code?
(Note: I am not asking about the interaction to invoke expand/collapse, I'm only asking what's the most appropriate way to lay out and set up my items.)
These days, use UICollectionView with different layouts and transitioning between layouts.

Resources