TextKit and VoiceOver - ios

I've been following the iOS7 Day-by-Day multi-page TextKit tutorial, and ran into an issue with accessibility. The code for the tutorial is here: iOS7 Day-by-Day
The problem is that each of the text views (one per column, two per "page") seems to contain the entire string, and with VoiceOver enabled, every time a column gets the focus, the text is read from the very beginning of the string to the very end, instead of reading the text that is actually visible in a column.
The textviews/columns are created using the new iOS7 method
UITextView *textView = [[UITextView alloc] initWithFrame:textViewFrame
textContainer:textContainer];
How can I get VoiceOver to read only the visible text in each column?

Sounds like you simply need to determine what text is visible and then pass that to VoiceOver.
To do that, you can use the two possible methods found in this related question and with the range of the visible text, you can then create a substring via something like:
NSString *textToPassToVoiceOver = [[textView.text] rangeOfSubstring:visibleTextRange];
Makes sense?

Related

Change NSAttribtuedString Formatting Starting at Index

I have a UITextView with attributes enabled, and I want to change the formatting (font/alignment/color/etc) within the NSAttributedString starting at a point. In other words, there is no specific part of the underlying NSAttributedString I want to change per se, I just want to make the next thing added into the UITextView have different formatting from what is in there so far.
For example, you might imagine a UITextVIew with a string inside it, and then the user enters a new line and taps a button to increase the font size. The user does not want to increase the font size of everything, just starting at that point.
Can this be done? Thanks.
If you need precise control over the dynamic style behavior of your UITextView (and if you are >= iOS 7), you should consider using Text Kit, and in particular subclassing NSTextStorage. There is a introduction video to Text Kit from WWDC 2013, and a great tutorial by Ray Wenderlich.

How do I bind an NSString to a UITextView in Reactive Cocoa?

I'm building an iOS social client, and in the "compose" view, I've got a UITextView where the user enters text. I'd like to use ReactiveCocoa to bind the text of the UITextView to the NSString of the data model, to follow MVVM.
However, I'm running into several issues, all related to a single thing: the RACObserve block doesn't get called when the UITextView's text is changed programmatically.
(An example: I change the text into an attributed string to highlight #hashtags, #usernames, etc, but this attributed string doesn't get created when the view is programmatically changed.)
In my previous question on this topic, I got some helpful advice that I should bind the textview to the model - and vice versa - but it's not clear to me how I should do it with the current version of Reactive Cocoa. The sample code that I've managed to find calls APIs that are now deprecated.
What's the appropriate way to bind the rac_textSignal of a UITextView to an NSString (and vice versa) so that I can reliably call a block of code when the contents of the UITextView are changed (whether programmatically or by the user)?
The answer depends on whether the binding between the view model's text and the UITextViews text needs to be bidirectional. Generally we try to stay away from bidirectional bindings because they become harder to reason about. Ideally only one direction is driving the data.
So in that case, you'd write something like:
RAC(self.viewModel, text) = [RACSignal merge:#[
[self.textView rac_textSignal],
RACObserve(self.textView, text),
]];
That way you're picking up on changes to both the UITextViews text property directly, and text changes that come from the user typing.

iOS Instagram Tags Text Layout? How Is It Done?

I've always been curious how instagram gets it's tags to layout fluidly and wanted to know what goes behind this functionality? To me, it seems like they're using UIButton's and just calculating placement of the buttons line by line? Is that right? Or is there a simpler method of doing it without having to manual calculate the placement of each tag line by line / or side by side given that multiple tag's width's fit together?
Or, are they using NSAttributedStrings?
Any ideas?
Here's an example of the layout I'm referring to.
Well, I'm currently working on NSAttributedString and UITextView to get all this working, and my current code can do it. So I'm going to explain a possible version of doing this.
Here are the tips and big steps, with iOS7:
NSAttributedString, in iOS7 has a new attribute : NSLinkAttributeName. You can add it to your NSAttributedString, and with a detection method (combining: how to make #key and #key clickable in IOS7 and Get word from tap in UITextView) you can manage it. That's for the general way of doing it. For previous version, you'll have to do a little more of work, but keeping this general idea.
But since, it only for hashtags, since you can detect the world behind the tap, you can do this: Detect what word has been tapped (see previous links), detect if this word has an hashtag, and if yes, you can do whatever action you want. You can play with a NSRegularExpression to know where are the hashtags, and know when to "color" them.
Here is a simplified way to do it using UITextView and NSAttributedString:
Use regular expressions to get character ranges for links.
Add link styling to the matched ranges.
Add custom attribute to range that references tap action to execute.
On touch, if index of character is inside a matched range, change the link formatting to highlight it and run the associated tap action.
How to get index of character at location in iOS7:
- (NSUInteger) getCharIndexAt: (CGPoint) location
{
NSLayoutManager *layoutManager = self.layoutManager;
NSUInteger characterIndex = NSNotFound;
characterIndex = [layoutManager characterIndexForPoint:location inTextContainer:self.textContainer fractionOfDistanceBetweenInsertionPoints:NULL];
return characterIndex;
}
Also check out WWDC 2013 intro to TextKit Demo
ios7 text utilities

UITextView with emoticons editing

I am developing xmpp-client app. One of the features is sending smiles and user should have ability to edit its like usuall text. Emoticons editing in Viber App is best example of what i want to implement.
I already tried three ways to solve problem:
I create emoticon like usual UIImageView and place it as a subview on UITextView using current caret rect. I use 5 whitespaces as a text placeholder in text view. There are two problems: with placing emoticons on new line when inserting text in the middle(printing whitespace not make caret move to new line); when user placing caret using magnify glass, he can move caret through emoticon(through 5 whitespaces), as delegate method not called during this process.
I have tried EGOTextView. There are problems with caret position and resizing when new line should be added. And there are some rendering artifacts when using it one line size.
I also have tried using UIWebView. But there were great problems with resizing based on text size and other artifacts with speed of response when becoming first responder.
May be some one could give me advice of really working solution?
I'm not really into rects and ranges mechanism of UITextView/UITextInput, but I try to give you an (untested) advice that maybe could achieve the expected result.
Built-in iOS emojis are simple characters, so we can follow the same path by building a custom font (or extend an existing one).
We have two options:
If you want to target iOS 6.0 (that has native support for NSAttributedString in UIKit classes), you could try to build a custom font containing all the emoticons you need, and use it inside your NSAttributedString (attributed string can mix different fonts, font sizes, styles and so on).
You could do something similar with iOS 5, but since you can't use NSAttributedString inside UITextView (so you are limited to just one font for the entire text) you should use a font that combines together the actual characters and the custom emoticons: so you should extend the font you want to use for typing, by adding all the emoticons to it. I don't know if this could have licenses implications, anyway.
Otherwise, you could always go much more low-level, implementing your own custom textView using CoreText, but I think it would be a hard work.

How to display more than one line in UIMenuItem?

I'm trying to display more than one line of text in a custom UIMenuItem.
I've tried using a simple "\n" in the title property of the UIMenuItem but with no luck.
Example:
UIMenuItem *menuItem; //Is then allocated properly....
// Before the Menu is displayed
menuItem.title = #"This is a first line.\nThis is a second line.";
Unfortunately I just end up with one line being displayed...
What I want to achieve is something similar to what you can see upon a LongPress on a row in the Apple iPod/Music app.
I've just found out about this github project as a solution:
https://github.com/questbeat/QBPopupMenu
You can display whatever custom UIView within a MenuItem. So I inserted a multi-line UILabel and that works.
However I would rather use the native Apple UIMenutItem approach if this is possible. Any ideas? Thanks in advance.
You would need to change some internal property of the UIMenuItem, but unfortunately Apple does not provide a way to do it.
So, as for today, there's not way to change the display of a UIMenuItem.
Have you tried '\r' instead of '\n'?

Resources