Share image in iMessage using Custom Keyboard in iOS 8 - ios

I am working on iOS 8 custom keyboard, where i have designed keyboard using some images like smiley. i want this keyboard to be work with iMessage. when i am trying to send text its working properly but can't able to share image there. I have tried following code :
To share text : (its working properly)
-(void)shouldAddCharector:(NSString*)Charector{
if ([Charector isEqualToString:#"Clear"]) {
[self.textDocumentProxy deleteBackward];
} else if([Charector isEqualToString:#"Dismiss"]){
[self dismissKeyboard];
} else {
[self.textDocumentProxy insertText:Charector];
}
}
To add image : ( Not working)
-(void)shouldAddImage:(UIImage*)oneImage
{
UIImage* onions = [UIImage imageNamed:#"0.png"];
NSMutableAttributedString *mas;
NSTextAttachment* onionatt = [NSTextAttachment new];
onionatt.image = onions;
onionatt.bounds = CGRectMake(0,-5,onions.size.width,onions.size.height);
NSAttributedString* onionattchar = [NSAttributedString attributedStringWithAttachment:onionatt];
NSRange r = [[mas string] rangeOfString:#"Onions"];
[mas insertAttributedString:onionattchar atIndex:(r.location + r.length)];
NSString *string =[NSString stringWithFormat:#"%#",mas];
[self.textDocumentProxy insertText:string];
}
Is there any possibility to pass image to [self.textDocumentProxy insertText:string];
following attached image shows how exactly i want to use this image keyboard. i am surprised how emoji keyboard will work?

As far as I know, the behavior you are looking for is not possible as of iOS 8 beta 4.
Currently, the only way for iOS custom keyboards to interact with text is through <UITextDocumentProxy> and the only way to insert anything is via the insertText: method.
Here is the header for the insertText: method in <UITextDocumentProxy>:
- (void)insertText:(NSString *)text;
As you can see, it takes a plain NSString... not an NSAttributedString. This is why your attempt to insert an image doesn't work.
However, despite the fact that you can't add pictures, it is still very possible to insert emojis, since an emoticon is really just a Unicode character.
To add an emoji, just insert the proper Unicode character:
[self.textDocumentProxy insertText:#"\U0001F603"];
Useful links:
List of Unicode Emoji: http://apps.timwhitlock.info/emoji/tables/unicode
Unicode Characters as NSStrings: Writing a unicode character with NSString

Related

Limiting text read by VoiceOver from a UILabel

I'm creating an app similar to Mail (or Messages or Notes) that displays UITableViewCells that contain a message preview. The text usually doesn't all fit in the UILabel, so the text is truncated and an ellipsis is displayed automatically. This works well in my app for sighted users, however when using VoiceOver the entire text content of the UILabel is read aloud. That does not occur in Mail - VoiceOver stops announcing text upon reaching the ellipsis.
How can I obtain the same behavior in my app as Mail - enforce VoiceOver stop announcing text when it reaches the ellipsis?
cell.messagePreviewLabel.text = a_potentially_really_long_string_here
Here is a subclass of UILabel that will do what you want. Note, I have gone to zero effort to optimize this. That part is up to you. My overall recommendation, from an accessibility point of view, would still be to simply leave it. Overriding an accessibility label to only portray a portion of the text in the actual label is a really questionable thing to do from an A11y perspective. Use this tool very carefully!
#interface CMPreivewLabel : UILabel
#end
#implementation CMPreviewLabel
- (NSString*)accessibilityLabel {
return [self stringThatFits];
}
- (NSString*)stringThatFits {
if (self.numberOfLines != 1) return #"This class would need modifications to support more than one line previews";
const int width = self.bounds.size.width;
NSMutableAttributedString* resultString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];
while (width < resultString.size.width) {
NSRange range = [resultString.string rangeOfString:#" " options:NSBackwardsSearch];
range.length = resultString.length - range.location;
[resultString.mutableString replaceCharactersInRange:range withString:#""];
}
return resultString.string;
}
#end

iOS: Column formatting for NSString not working in UITextView?

I'm working on an iPad app and I need to be able to format some output on the screen in a columnar format. This was similar to my question:
How can I use the \t [tab] operator to format a NSString in columns?
and I used that solution, unfortunately I'm not seeing the same results. My code is as follows:
NSString* titleColumn = [[NSString stringWithFormat:#"%#", displayName] stringByPaddingToLength:25 withString:#" " startingAtIndex:0];
NSString* serializedValue = [[NSMutableString alloc] init];
NSString* valueAsString = [NSString stringWithFormat:#"%.03f", value];
serializedValue = [serializedValue stringByAppendingFormat:#"%#%#", titleColumn, valueAsString];
When logging the items in the console, they are properly aligned, however, when plugging them into a UITextView, they are misaligned. This is how I'm sticking them in the text view:
NSMutableString* displayString = [[NSMutableString alloc] initWithString:#""];
for (NSString* entry in textToDisplay)
{
NSLog(#"%#", entry);
[displayString appendString:entry];
[displayString appendString:#"\n"];
}
[self.fTextPanel setText:displayString];
Any ideas on what I'm doing wrong?
EDIT:
In the log, it looks like this:
Inclination 0.000
Version 0.000
Inferior/Superior 0.000
Anterior/Posterior 0.500
And the UITextView version looks like this: http://imgur.com/vrUzybP,OYxGVd8
The reason for misaligned is the different width for each character. The best way for displaying this type of information is by using UITableView, You can use title and subTitle field for displaying or you can design a custom UITableView.
the reason is because when drawing charachters (glymphs), each character will have different widths,i.e character small c and big C will take different widths for drawing , so it wont work. Even though there are two strings with equal lengths but different characters, the drawing text will have different widths.
What i would suggest you for this is to have two textViews side by side, render titles in one textVIew and values in the next TextView.
If the number of titles is large and if you enable scrolling in textVIews, use delegate Methods of UIScrollView, and when scrollHappens in either of them, set the contentOffset of the other to make it look like single TextView.
Hope this helps.

Text character location changed when UITextView has Under line text in iOS 6

In my app i am giving command to user to create Bold,Italic and UnderLine text.
Bold and Italic text is coming perfectly.
and also Underline text working Perfectly in iOS 7.
But When used that code in iOS 6 the Underline will come under the text but the next character will come on range.location=0.
I just want the text go smoothly with UnderLine Text when User type.
My code for UnderLine Text is
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSLog(#"shouldChangeTextInRange %d - %d - %d",range.location,range.length,txtViewOfNotes.attributedText.length);
if (range.location==0) {
NSLog(#"location 0");
}
else{
NSLog(#"location 123");
NSMutableAttributedString *mat = [txtViewOfNotes.attributedText mutableCopy];
[mat addAttributes:#{NSUnderlineStyleAttributeName: #(NSUnderlineStyleSingle)} range:NSMakeRange (mat.length-1, 1)];
txtViewOfNotes.attributedText = mat;
}
}
OutPut for Example:
e
n
i
l
I am typing now txtUnder
Any one know why this is happening in only iOS 6.
You should just update the [textView textStorage] attributes rather than making a copy of the attributed string and replacing it.
So get rid of the mutableCopy line of code and replace the next line with:
[[textView textStorage] addAttribute:...]
Your code is completely replacing the textView's attributed string and as a consequence the cursor position is being reset. No need to replace it, just add attributes to the existing textStorage (which is already a mutableAttributedString).
See here for more on formatting text and images in UITextView and NSTextView.

Why is textView:shouldInteractWithTextAttachment:inRange: never getting called on UITextView delegate?

Is anyone using this delegate method ? I get callbacks on
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
But not on this one. The documentation seems a bit ambiguous about what this is intended for
- (BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange
According to the documentation on the Web this is what its intended for:
Discussion
The text view calls this method if the user taps or long-presses the text attachment and its image property is not nil. Implementation of this method is optional. You can use this method to trigger an action in addition to displaying the text attachment inline with the text.
And here is Xcode 5 documentation:
Asks the delegate if the specified text view should display the provided text attachment in the given range of text.
The text view calls this method when a text attachment character is recognized in its text container by a data detector. Implementation of this method is optional. You can use this method to trigger an alternative action besides displaying the text attachment inline with the text in the given range.
EDIT:
Mmm OK I figured out the problem. If I paste an image in from iOS then it works, however if the image was pasted in from OS X it does not. It seems that the actual attachment formats used are not quite the same on both platforms despite the fact that the image appears to show up correctly in the text views. On closer inspection the NSTextAttachment classes don't appear to be the same on iOS as on OS X.
If anyone can shed any light on the cross platform compatibility here please do.
Also if I save the attributed string after pasting the image in on iOS and then retrieve it and display it in the UITextView interaction with the attachment is no longer possible. It would appear that when storing the image the image is actually placed in contents if contents is nil. So maybe I am going to have to iterate through all attachments to check what data is stored where particularly to figure out any differences in behaviour across the OS X and iOS platforms.
FURTHER EDIT:
The method only gets called if the attachment image is NOT nil and despite the fact that an image is displayed the actual image attribute can actually be nil, silly me! Anyway the fix seems to be to check all the attachments in the attributed string and to set their image attribute to something, usually the contents of the fileWrapper. The default NSTextAttachment behaviour seems to be to store the image in the fileWrapper when its archived but it does not do the reverse when its unarchived. Anyway I want to retain the original image in the attachment but depending on the device display a suitably scaled version of the original !
The chief thing is that the text view's editable property must be NO and it's selectable property must be YES. Those are the only circumstances under which this delegate method is called. If you are getting shouldBeginEditing then your text field is editable which is exactly what it must not be.
Here is what I do to ensure the NSTextAttachments image attribute gets set when restoring the UITextView's attributed string from archived data (in this case whenever the user selects a record from a Core Data store).
I set the UITextView up as a delegate for textStorage and in the didProcessEditing look for any attachments that may have been added and then check that their image attribute is set. I am also setting the scaling factor on the image to make sure the image scales appropriately for the device.
This way I don't loose the original resolution of the image and if the user wants to view it in more detail I provide the option to open it in an image browser window from a popup menu.
Hope this helps someone else.
EDIT:
Check here for more details on NSTextView and UITextView http://ossh.com.au/design-and-technology/software-development/
- (void)textStorage:(NSTextStorage *)textStorage didProcessEditing:(NSTextStorageEditActions)editedMask range:(NSRange)editedRange changeInLength:(NSInteger)delta {
//FLOG(#"textStorage:didProcessEditing:range:changeInLength: called");
[textStorage enumerateAttributesInRange:editedRange options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:
^(NSDictionary *attributes, NSRange range, BOOL *stop) {
// Iterate over each attribute and look for a Font Size
[attributes enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([[key description] isEqualToString:NSAttachmentAttributeName]) {
NSTextAttachment *attachment = obj;
//Reset the image attribute and scale for the device size if necessary
[self resetAttachmentImage:attachment];
}
}];
}];
}
- (void)resetAttachmentImage:(NSTextAttachment*)attachment {
UIImage *image = [attachment image];
float factor = 2;
if (image == nil) {
if (attachment.fileWrapper == nil || !attachment.fileWrapper.isRegularFile) {
attachment.image = [UIImage imageNamed:#"unknown_attachment.png"];
return;
}
//Usually retrieved from store
image = [UIImage imageWithData:attachment.fileWrapper.regularFileContents];
} else {
// Convert any pasted image
image = [UIImage imageWithData:UIImagePNGRepresentation(image)];
}
float imgWidth = image.size.width;
// If its wider than the view scale it to fit
if (imgWidth > _viewWidth) {
factor = imgWidth / _viewWidth + 0.5;
attachment.image = [UIImage imageWithData:UIImagePNGRepresentation(image) scale:factor];
} else {
attachment.image = [UIImage imageWithData:UIImagePNGRepresentation(image) scale:_scale];
}
}

Change size of text in UITextView based on content of NSString

I am trying to load a UITextView with content from instances of a NSManagedObject subclass (verses in a Bible reader app).
My UITextView is loaded by iterating through the verses in a selected chapter and appending each consecutive verse.
NSArray *selectedVerses = [[Store sharedStore] versesForBookName:selectedBook
ChapterNumber:selectedChapterNum];
displayString = #"";
for (Verse *v in selectedVerses) {
NSMutableString *addedString =
[NSMutableString stringWithFormat:#"%d %#", [v versenum], [v verse]];
displayString = [NSMutableString stringWithFormat:#"%# %#", addedString, displayString];
}
NSString *title = [NSString stringWithFormat:#"%# %#", selectedBook, selectedChapter];
[self setTitle:title];
[[self readerTextView] setNeedsDisplay];
[[self readerTextView] setText:displayString];
The above code generates the correct view, but only allows for one size of text for the entire UITextView.
I would like to have the verse number that precedes each verse to be a smaller size font than its verse, but have not found a way to make it work. I've been reading through the documentation, and it seems that this should be possible with TextKit and CoreText through the use of attributed strings, but I can't seem to get this to compile.
I do not want to load the view as a UIWebView.
Any suggestions for this are greatly appreciated.
You're looking for NSAttributedString and NSMutableAttributedString. You should read Introduction to Attributed String Programming Guide. They're generally like normal strings, but additionally contain attributes with ranges to which they apply. One more method that would be helpful to you is:
[self readerTextView].attributedText = yourAttributedString;
If you have some specific problems with attributed strings, please post your code.

Resources