How to do Scrolling Lyrics with animation? - ios

In my app, I want to add scrolling lyrics, like UIPickerView rolling lyrics, according to the song. I tried Cloud Label In Code4App (http://code4app.net/ios/Tab-cloud/5235d23f6803fa2f7b000000) but I'm not understanding that code since I'm new to Obj-C!
Can anyone please help me or suggest tutorials?

I don't think you're going to be able to use a UIPickerView for what you're describing since I don't think there's any way to do a slow controlled scroll on a UIPickerView, especially while changing the text characteristics continuously.
I think you might be better off using a UITableView, animating the content offset to scroll, and using attributed text to change the highlights.
I don't know how to get that circular UIPickerView "look" you're trying to achieve though. That might be more complicated...

I agree with Lyndsey that a picker view is not the right tool for what you are trying to do.
If you are a beginner at Objective C this is probably over your head. Way, way over your head even.
You would need to use Core Animation on the layers of a set of text views, and rotate those views around the Y axis, with the center of rotation being behind the view. You'd need to manipulate the transformation matrixes that you apply to each layer to get a perspective effect (applying a value of around -1/500.0 to the m34 entry in the CATransform3D)
For now I would suggest giving up on 3D rolling perspective, and just using UIView animation (look at the method animateWithDuration:animations: and it's cousins. That's nice and easy to use.

Related

How to create a collection view with images that change size on scroll

I want to implement an horizontal collection view displaying images that increases the size of the images with a smooth animation as they approach the center and reduces their size as they move away.
I have been studying the UICollectionView potentials but so far I have not been able to understand if such behaviour is possible to be implemented using UICollectionView or what would be the best alternative. For instance using UIScrollView instead (with a lot more work probably).
Some guidance or sample code would be most welcome. Thank you.

How to improve UILabel performance in a table view?

I have a table view with custom cells and I am trying to optimize it to make the scrolling as smooth as possible. I've followed most of the advises about table view optimization, for example, using fixed heights, not using AutoLayout etc.
I have achieved in a very optimized state except one thing. The custom cell has one image and several UILabels. With one image & 3 labels, the performance is perfect. However, when I add the 4th label, I start to observe a bit of jerkiness, very small but not as smooth as before.
I have searched the net and found CoreText can help performance. Is CoreText a right direction? Are there any other things that can help to improve UILabel performance when used in a table view?
EDIT:
I only use simple functions for UILabel by setting its font, font color, text and numberOfLines.
Core text is probably the ultimate solution for performance, but even before getting there I like to use a program called PaintCode to draw up the contents of my cells if they are particularly complicated.
Other things you can do however to speed things up a bit before you need to get to that point:
Do all calculations before cellForRow is called. So any number formatting, date calculations etc, should all be done and stored on your model object beforehand. That way you can just plug them straight in to your cells properties and they're ready to be displayed. Any extra time spent in cellForRow will slow down your tableview.
Set all labels and views to opaque. You'll probably have to set their background color when you do this, but it makes drawing the views that much faster. You can see which views have transparency applied by turning on "Color Blended Layers" from the debug menu for the simulator. What you want is to have your cells completely green.
Keep some dummy text in all labels by default. Updating text would not cost memory.
CoreText is pretty expensive and probably not meant for this! I think dummy text tricks should work for you.
Hope this works.

What's the best way to implement a vertical timeline - iOS

First of all, apologies if this question isn't meant here. I searched a lot but didn't find anything.
What is the best approach to create a vertical timeline kind of view?
I tried implementing via UITableView by alternating cells but that approach is very messy in terms of autolayouting (had to disbale autolayout and apply programtically when creating cell on alternate side), thereofre isn't working properly (getting stuck while scrolling). This is what I achieved:
I want to achieve something like this, which is also easily manageble:
Please Suggest. Thanks!
I would have 1 cell row with two image views. One on the left, one on the right. I think this would be easier to use auto layout.
Then you can hide the image view and labels that shouldn't be used.

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.

Masked scrollable button list

I want to implement scrollable button list which are displayed inside popup. I would need some kind of masking, but buttons should also work inside mask. Any suggestions how to do it?
It is possible to achieve this with CCMask class but this is pretty slow way to do it as mask has to be applied every update.
If you use this class you will also loose button detection so you will have to play with touch detection. You will also nead a lot of tweaks to position mask & objects exactly where you want.
When you will finish everything it will not be as good as you thought it will be .. The feeling of scrolling will just not be OK, since there will be masking lag ...
It is better to hide hidden parts of scrollable items with some kind of "window" images

Resources