Detecting finger touch on text - iphone

I want to read the string displayed on the screen with finger touch, means as my finger moves over the text displayed on screen, the text below the finger should get highlighted. Is there any way to do this using UITextView or any other class. Also i want to play the sound associated with that word from a sound file which has the sentence already recorded.
If anyone knows it kindly reply.
Thanks in advance.

So that's two questions.
To know where your finger is pointing in the text you need to know where the UITextView has laid out the characters. This is not something the UITextView is documented to support, so next up is drawing text yourself. This stackoverflow question on embedding a custom font has a few links and even some code that will do the trick. What you need to add is keeping track of character advances so you know exactly where each character is rendered (or you could even use other core graphics functions to get exact bounding boxes of each character).
Clearly once you know what character has been tapped you also know the word it is part of. You'll would probably have the best quality if the sentence is recorded both in full and as single words, so that you can play back either when needed. This other stackoverflow question on playing sounds loaded from the internet has a few links and snippets which relate to loading and playing back audio.

I am doing this in an iPhone text editor I am writing. For multiple reasons, I have subclassed a UIView to draw the text (instead of a UITextView) and I had to implement something like this to provide a movable cursor like a text view has. What I did was use a fixed-width font (Courier to be exact), then I took the x-coordinate of the touch and divided it by the width of the character and rounded the answer down. This gives you a character index.
However, if it is possible, find a way to do this without drawing the text yourself (if the text is user entered or really anything other than hardcoded) because Apple provides a lot of functionality in its UITextView class that is a pain to replicate: editing, cursor, word wrap, scrolling, etc.
It might be possible, if you can't get touch events from a subclassed UITextView, to put a transparent view/layer over the top of the text and get touch events from that, then you would only have to figure out a way to turn this on and off for editing.
Kyle

I came up with a handy trick to do this. In drawRect, mimic the text that the UITextView will draw, but don't actually draw the text. Set the font to Helvetica 17-point, and the only semi-tricky part is handling word wrapping. You already have the text to be displayed, and you can get the size of each word in that default font by calling sizeWithFont. Then save the rectangles for each word, and when the user touches the view, find which of the stored rectangles contains the touched point. To test and calibrate the geometry (line spacing, etc), draw the text yourself in a different color. When you get it so that you can only see one of the font colors, you've got it perfect.
I can post my code for this if someone wants it.

Related

How to vertically center individual characters of a text string?

I am working on an iPhone app (Swift and Storyboard) and I would like to show some text, e.g. the price of a product people can buy, inside a box, as shown in the image. Nothing special, just an image of a box, with a UILabel on top of it, vertically entered, so the text fits nicely within the box.
This is fine if only numbers are used, but if the text includes (lowercase) letters, the letter is not centered (example in red).
I know that this is how fonts work, and it depends on the baseline and ascender/descender of the character, etc.
But what I would like to do, is vertically center each individual character, so that a text like "200 p" ends up looking like the example in blue.
I quite extensively searched the internet and tried something myself with UILabel and a little bit of CoreText, but until now didn't find a solution to this.
You would think (well, I would think), that this kind of problem would already been solved, but I am unable to find it.
Does anybody know how to do this? So vertically center the characters in a string so that their (visual) vertical centers line up. Or is there maybe some 3rd party library that is able to do this?

Swift: Giving a single, long string of text tilt physics

I am building an experimental reading app where the text passage is presented as a single line of text on the screen. The user will tilt back and forth to move the text strip backwards or forwards. What I have tried so far is:
Placed a UILabel inside a UIScrollView and manually calculating the ScrollView’s new offset depending on the current tilt. The text scrolls in an uncomfortable, jerky motion in this implementation most likely because the current acceleration equation is just a linear function. Also, I’d rather not reinvent the wheel since Sprite Kit already has tilt physics perfected, but it is just not readily applicable on text objects.
Wanting to use Sprite Kit’s buttery smooth tilt, I placed my text in an SKLabelNode and had its X coordinates match a SKSpriteNode that I gave tilt physics. This worked very well until the moment I added a paragraph’s worth of text inside the SKLabelNode. Then it turns into a black rectangle...
Stack Overflow discussions I have found concluded that SKLabelNode is not meant to be used in the way I desire and have suggested multiline implementations, or string to bitmap image conversion. Multiline is not an option for the way I want my reading app to work.
I found the code in
How do I add text to an image in iOS Swift to implement string to bitmap image conversion, then making that image an SKSpriteNode. The moment the image’s width exceeds 2000 (only enough space for a short sentence in 50 pt font), it becomes a black rectangle. I imagine up the text into smaller chunks to fit inside this 2000 limit will really complicate the code and make user statistics like words per minute much harder to calculate.
At the top is what I want the text to look like (user tilts left/right to read next/previous), and the black strip on the bottom is the black rectangle that appears if the width of the text is way too long :(
Does anyone have any suggestions for what else I could try? Once again, my requirements are:
The string must be presented as a long, single line on the screen
The user tilts the device to read forward/backward
The acceleration is smooth so it’s easy on the eyes :)
Perhaps you can try loading one sentence at a time into one SKLabelNode. You will also have a second SKLabelNode to act as the on-deck cache. When one SKLabelNode moves off the screen, you can position it at the end of the of the SKLabelNode currently on screen. That's how a table view in UIKit works. The only difference here is that your "table cells" are scrolling horizontally, and you'll have to perform the work to reset them after they move off the screen.

How to center a UIActivityIndicatorView along with text (UILabel)?

I've had this issue come up a couple times doing iPhone development now and have yet to find a good solution for it. What I'm looking for is this:
I want to show some text along with an icon and I want the overall display to be centered within its parent view. Specifically, in my current case, I'm looking to display a box that says "Reconnecting..." with a UIActivityIndicatorView to the left of the text.
Previously, I've just relied on the fact that I know exactly the dimensions of the text and activity indicator, so I can position things absolutely to appear centered. What I'm looking for is something more automatic.
Any ideas?
One of the UIKit additions to NSString will return the pixel size of the text if you give it the font that you're using on the UILabel. So then presumably the total size of the two things together in the layout you describe is:
the difference between label.frame.origin.x and activityIndicatorView.frame.origin.x; plus
the width of the text.
You can then either shuffle both the views appropriately or give them a common parent that's still a subview of the whole thing and shift that.
An activity indicator can be shown in a view just calling a single method.Please click here get SHKActivityIndicator class

Highlight the text in webview when figer moves over the text in iphone?

I want to highlight the text when I drag the finger over the text in webview. I am able to detect the gesture and the coordinates at the point touched, but I am not able to highlight the text when I drag my finger over the text.
Any sample codes would be helpful.
Maybe you should do it by using JS.
For example, try http://www.jqtouch.com/, detect touch and change CSS Properties :-)
It's the best way I have in mind.

Creating a custom text-drawing view

I am creating a syntax highlighter for the iPhone and in order to display text with multiple formats, I have sub-classed UIView and modified the drawRect: method so that each line is displayed with the proper syntax highlighting (highlighting is done earlier with RegEx, text is drawn with CGContextShowTextAtPoint() one line at a time). Everything works ok, I store each line of text as an NSString in an NSMutableArray, I handle the keyboard through a hidden UITextField and its delegate methods, the cursor is a blinking CALayer that can be moved around with touches and I have a custom scroll view that handles scrolling. However, I have two problems that I can't seem to wrap my head around:
Word wrap, right now the text just keeps going off the left end of the screen. To keep things fast I only redraw the portions of the view that have changed (usually just the line being edited, but sometimes the lines below as well e.g. if you press return halfway through the document) with setNeedsDisplayInRect:. This makes word wrap complicated because then you have to draw more than one line on the screen, even though it still is only one object in the array.
UIViews have a maximum content size of 1024x1024 which equates to about 64 lines. I need the ability to display more than that. I am thinking about using multiple CALayers one after another, but I am having trouble drawing content to the layers (using drawLayer:inContext: and drawInContext:).
So my questions are:
Does anyone have any, even general, suggestions about how to accomplish either of these two points. Or,
Has someone already written a custom text-drawing view that handles these things that I could use instead.
Thanks,
Kyle
EDIT: The scrolling problem is pretty much solved, however I am still having trouble with word-wrap. My trouble is that everything is done by line: the view updates one line at a time, the text is stored as an array of lines, the highlighter highlights one line at a time, etc. and having a single index in the array (one line of text) take up multiple lines on the screen raises some problems, for example, I had to implement my own movable cursor and when you move the cursor it needs to be able to turn a display line (found by dividing touch.x by the line height) into a text line (an index in the array). Any ideas?
You should first spend some quality time understanding how this problem was solved on Mac:
http://developer.apple.com/documentation/Cocoa/Conceptual/TextArchitecture/Tasks/AssembleSysByHand.html
http://developer.apple.com/documentation/Cocoa/Conceptual/TextLayout/TextLayout.html
In particular, you should become familiar with line fragment generation, which is the problem you're trying to solve for word-wrap, and you should understand glyph generation in order to do rich text well. You don't need to implement all of the flexibility of NSTypesetter or NSLayoutManager of course, but the text system on Mac is incredibly powerful, and you should learn from its example. Implementing something similar to NSAttributedString for iPhone may be valuable to you and improve your performance.
Unless you're moving things around a lot (for which this would best work in a UIScrollView), I don't think you should need to use CALayers here. That seems overkill for the problem, and may actually adversely impact the optimizations already provided by UIScrollView. If you're seeing performance problems, first make sure you're not doing redundant calculations within your drawRect:.
Check out TTStyledText in Three20 library. Not sure how well it matches your goals, but might serve you as an example. (The library itself is a bit bloated, but is a wonderful source to look at.)
It may be best to draw your text within a CATiledLayer hosted within your UIView, in order to get around the 1024x1024 texture size limit (which appears to actually be 2048x2048 on all existing devices). For an example of text drawing within a CALayer, I'd refer you to the CPTextLayer class within the Core Plot framework. This layer (which inherits from the CPLayer class within that same framework) does cross-platform (Mac and iPhone) text rendering in a CALayer. You might be able to extend it to work as a CATiledLayer for longer text blocks.
One thing to be aware of is that platform-specific drawAtPoint: methods are used in this layer, instead of the CGContextShowTextAtPoint() function you are using. The reason for this is that CGContextShowTextAtPoint() only works on ASCII text, meaning that you can't do Unicode text rendering with it. There is an example of using CGContextShowTextAtPoint() to draw text, within a #define'd out portion at the bottom of the renderAsVectorInContext: method.