How to insert NSAttributedString text and image GIF(auto play) to UItextview? - ios

I use NSAttributedString text ,and want attachment gif image to show in UItextview
below mycode dostn't work for gif image
let mytext = UITextview()
let result = NSMutableAttributedString()
let attachment = NSTextAttachment()
attachment.image = UIImage(named:"abc.gif")
let attachmentString = NSAttributedString(attachment: attachment)
let myString = NSMutableAttributedString(string:"")
myString.appendAttributedString(attachmentString)
result.appendAttributedString(myString)
mytext.attrbutedText = result
Please help to resolve Attachment gif image
And it will play automatically.
Thanks in advance

Hi Please Try out this:
UIImageView * imageview =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"download.gif"]];
NSMutableArray *exclutionPaths = [NSMutableArray array];
[exclutionPaths addObject:[UIBezierPath bezierPathWithRect:CGRectInset(imageview.frame, -4, 0)]];
[_textView.textContainer setExclusionPaths:exclutionPaths];
[_textView addSubview:imageview];
_textView.text=#"Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...Blah...";

Related

GIF Image as Marker in Google Map for iOS (Swift)

I've this gif image:
I am able to add a custom static image as marker using the following code:
if let location = locationManager.location {
currentLocationMarker = GMSMarker(position: location.coordinate)
currentLocationMarker?.icon = UIImage(named: "user")
currentLocationMarker?.map = mapView
currentLocationMarker?.rotation = locationManager.location?.course ?? 0
}
I want to use this gif image as marker. Is there anyway? Though I know static images are encouraged but is there a possibility?
I was thinking of adding a UIView say a 100x100 view and animating this icon in it, haven't tried it but I tried the solution mentioned in this thread: How to load GIF image in Swift? as:
let jeremyGif = UIImage.gifImageWithName("puppy")
let imageView = UIImageView(image: jeremyGif)
imageView.frame = CGRect(x: 0, y: 0, width: jeremyGif?.size.width ?? 100.0, height: jeremyGif?.size.height ?? 100.0)
//view.addSubview(imageView)
//mapView.addSubview(imageView)
if let location = locationManager.location {
currentLocationMarker = GMSMarker(position: location.coordinate)
currentLocationMarker?.icon = imageView.image //UIImage(named: "user")
currentLocationMarker?.map = mapView
currentLocationMarker?.rotation = locationManager.location?.course ?? 0
}
but doing so also doesn't work. I've added this gif image in assets and this is how it appears in it:
I've got it. So here is the solution:
Add the gif image in project folder not in assets.
Make a new swift file and copy/paste the code from this Link: https://github.com/kiritmodi2702/GIF-Swift/blob/master/GIF-Swift/iOSDevCenters%2BGIF.swift
Add this code where you want to have the gif image. In my case I'm placing it at user location:
func addCurrentLocationMarker() {
currentLocationMarker?.map = nil; currentLocationMarker = nil
let puppyGif = UIImage.gifImageWithName("Puppy")
let imageView = UIImageView(image: puppyGif)
imageView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
if let location = locationManager.location {
currentLocationMarker = GMSMarker(position: location.coordinate)
currentLocationMarker?.iconView = imageView
currentLocationMarker?.map = mapView
currentLocationMarker?.rotation = locationManager.location?.course ?? 0
} }
and it works:
Thank for your question and answer. Main idea here is overwrite GMSMarker.iconView by using UIImageView that display Gif Image
I used your idea for my implementations which may be a little complex than your answer but not use 3rd library
Firstly, I export gif image to sequence of png images by this tool https://onlinepngtools.com/convert-gif-to-png
Then I create UIImageView that animate those PNG
UIImageView * gifImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 24, 24)];
gifImageView.animationImages = #[ [UIImage imageNamed:#"gifToPngFrame01"]
,[UIImage imageNamed:#"gifToPngFrame02"]
,[UIImage imageNamed:#"gifToPngFrame03"]
,[UIImage imageNamed:#"gifToPngFrame04"]
,[UIImage imageNamed:#"gifToPngFrame05"]
,[UIImage imageNamed:#"gifToPngFrame06"]
,[UIImage imageNamed:#"gifToPngFrame07"]
,[UIImage imageNamed:#"gifToPngFrame08"]
,[UIImage imageNamed:#"gifToPngFrame09"]
,[UIImage imageNamed:#"gifToPngFrame10"]
,[UIImage imageNamed:#"gifToPngFrame11"]
,[UIImage imageNamed:#"gifToPngFrame12"]
,[UIImage imageNamed:#"gifToPngFrame13"]];
gifImageView.animationRepeatCount = 0;
gifImageView.animationDuration = 1;
CLLocationCoordinate2D position2 = CLLocationCoordinate2DMake(21.033333, 105.87);
GMSMarker *gifMarker = [GMSMarker markerWithPosition:position2];
gifMarker.iconView = gifImageView;
gifMarker.map = mapView;
gifMarker.groundAnchor = CGPointMake(0.5, 0.5);
[mapView animateToLocation:position2];
[gifImageView startAnimating];
This code uses objective c. But I think It may give additional benefit for others about this topic

UIImage next to centered UITextField Placeholder Text

What would be the best approach for aligning a UIImage icon next to the centered placeholder text of a UITextField? Ex:
I have been attempting to replicate this for sometime now and can't seem to reach the desired effect.
I've tried using the LeftView of the UITextField however can't get this aligned next to the placeholder text (I thought about adding padding to the LeftView by changing it's frame but am unsure how I would obtain the values needed to align it next to the placeholder. There does not appear to be away to get the coordinates for the placeholder text.) . I've also tried to subclass UITextField but here am again unsure on how to obtain the proper coordinates.
You can attach images inside attributed strings using NSTextAttachment
Swift 3.0
txtField.textAlignment = .center
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "searchIcon")
attachment.bounds = CGRect(x: 0, y: 0, width: 10, height: 10)
let attachmentStr = NSAttributedString(attachment: attachment)
let myString = NSMutableAttributedString(string: "")
myString.append(attachmentStr)
let myString1 = NSMutableAttributedString(string: "Find a Location (Zip Code or Name)")
myString.append(myString1)
txtField.attributedPlaceholder = myString
Objective-C
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [UIImage imageNamed:#"searchIcon"];
attachment.bounds = CGRectMake(0, 0, 10, 10);
NSAttributedString *attachmentStr = [NSAttributedString attributedStringWithAttachment:attachment];
NSMutableAttributedString *myString = [[NSMutableAttributedString alloc] initWithString:#""];
[myString appendAttributedString:attachmentStr];
NSMutableAttributedString *myString1 = [[NSMutableAttributedString alloc] initWithString:#"Find a Location (Zip Code or Name)"];
[myString appendAttributedString:myString1];
txtField.attributedPlaceholder = myString;

Add Carousel View inside Textview

I am adding data into TextView through sqlite database. I have around 30 to 35 images to be added in it after some Para or Line of data, which i have done through NSTextAttachment. Now what i want to do is wherever there are more that 2 images i want it to be in Carousel View and remaining data after it. Have a look at my code. I tried the different way but not getting success. Any help will be much appreciated.
NSTextAttachment *textAttachment1 = [[NSTextAttachment alloc] init];
textAttachment1.image = [UIImage imageNamed:#"img1.png"];
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:#"img2.png"];
NSTextAttachment *textAttachment2 = [[NSTextAttachment alloc] init];
textAttachment2.image = [UIImage imageNamed:#"img3.png"];
NSTextAttachment *textAttachment3 = [[NSTextAttachment alloc] init];
CGFloat oldWidth1 = textAttachment1.image.size.width;
CGFloat oldWidth = textAttachment.image.size.width;
CGFloat oldWidth2 = textAttachment2.image.size.width;
CGFloat scaleFactor1 = oldWidth1 / (self.textViewResearch.frame.size.width + 70);
CGFloat scaleFactor = oldWidth / (self.textViewResearch.frame.size.width + 70);
CGFloat scaleFactor2 = oldWidth2 / (self.textViewResearch.frame.size.width + 70);
textAttachment1.image = [UIImage imageWithCGImage:textAttachment1.image.CGImage scale:scaleFactor1 orientation:UIImageOrientationUp];
textAttachment.image = [UIImage imageWithCGImage:textAttachment.image.CGImage scale:scaleFactor orientation:UIImageOrientationUp];
textAttachment2.image = [UIImage imageWithCGImage:textAttachment2.image.CGImage scale:scaleFactor2 orientation:UIImageOrientationUp];
NSAttributedString *attrStringWithImage1 = [NSAttributedString attributedStringWithAttachment:textAttachment1];
NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment];
NSAttributedString *attrStringWithImage2 = [NSAttributedString attributedStringWithAttachment:textAttachment2];
[attributedString replaceCharactersInRange:NSMakeRange(0, 0) withAttributedString:attrStringWithImage1];
[attributedString replaceCharactersInRange:NSMakeRange(13740, 0) withAttributedString:attrStringWithImage];
[attributedString replaceCharactersInRange:NSMakeRange(13741, 0) withAttributedString:attrStringWithImage2];
self.textView.attributedText = attributedString;
If I understood you correctly, you want to place an image inside a text view and let the text flow around it. Having more than 2 images you want to have a carousel, an instance of the class iCarousel.
Having a subview inside an instance of UITextView and letting the text float around it, is a known tasks. The easiest way seems to be to use the exclusion path of a text container like this:
// Get the dimension of the subview
iCarousel *subview = …;
UIBezierPath *subviewPath = [UIBezierPath bezierPathWithRect:subview.frame];
// Somewhere you should add it
UITextView *textView = …; // Wherever it comes from
[textView addSubview:subview];
// Let the text flow around it
UITextContainer *textContainer = textView.textContainer; // The text container is the region text is laid out in.
textContainer.exclusionPaths = [subviewPath]; // Do not lay out in this region.
Of course you have to change the exclusion region, whenever the frame of the subviews change.
A more flexible and more complex approach is to do the text layout your own. If the above approach does not work, let me know. I will add code for this.

How to append text in UITextView

I have a UITextView with random properties and random size. I need to append a watermark written into a UITextView. But the watermark needs to have different text properties and different alignment .
Example:
This is the UITextView with random properties.
This is the watermark.
You need to use attributed strings (NSAttributedString) instead of strings (NSString).
UITextView has a text property and an attributedText property. In your case, use the attributedText property once you have created the attributed string.
Try using attributed string:
NSString *textViewText = #"...";
NSString *watermarkText = #"\nThis is the watermark";
NSString *fullText = [textViewText stringByAppendingString:watermarkText];
NSMutableParagraphStyle *watermarkParagraphStyle = [NSMutableParagraphStyle new];
watermarkParagraphStyle.alignment = NSTextAlignmentCenter;
NSMutableAttributedString *fullTextAttributed = [[NSMutableAttributedString alloc] initWithString:fullText];
[fullTextAttributed addAttribute:NSParagraphStyleAttributeName
value:watermarkParagraphStyle
range:[fullText rangeOfString:watermarkText]];
textView.attributedText = fullTextAttributed;
Here's a translation of #skorolkov's Objective-C code:
let textViewText = "..."
let watermarkText = "\nThis is the watermark"
let fullText = textViewText + watermarkText
let watermarkParagraphStyle = NSMutableParagraphStyle()
watermarkParagraphStyle.alignment = NSCenterTextAlignment
let fullTextAttributed = NSMutableAttributedString(string: fullText)
fullTextAttributed.addAttribute(NSParagraphStyleAttributeName,
value: watermarkParagraphStyle,
range: fullText.rangeOfString(waterMarkText))
textView.attributedText = fullTextAttributed

Place an UIImage after an UILabel

I want to have an UILabel with a max width of 100 and after that an UIImage, how can I do that in interface builder? I want that if the text is shorter the label is less than 100 but the UIImage is right behind the label.
You can use NSTextAttachment class available from iOS 7.No need to play with the frame.
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [UIImage imageNamed:#"image.png"];
NSAttributedString *attachmentAttrString = [NSAttributedString attributedStringWithAttachment:attachment];
NSMutableAttributedString *str= [[NSMutableAttributedString alloc] initWithString:#"hello"];
[str appendAttributedString:attachmentAttrString];
myLabel.attributedText = str;
you can do it with code like this:
first init the label and the imageView
_label = [[UILabel alloc] initWithFrame:CGRectZero];
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(label.frame.origin.x + label.frame.size.width, label.frame.origin.y, 30, 30)];
then when the label has text , you can calc the width of the label`s frame
CGSize size = [_label.text sizeWithFont:[UIFont boldSystemFontOfSize:15]];
CGFloat width = size.width > 100 ? 100 : size.width;
CGFloat height = size.height;
_label.frame = CGRectMake(0, 0, width, height);
I'd like to add my swift solution:
let label = UILabel()
let attributedString = NSMutableAttributedString(string: "Hello".uppercaseString)
let attachment = NSTextAttachment()
attachment.image = UIImage(named:"hello")
attributedString.appendAttributedString(NSAttributedString(attachment:attachment))
// use the following method to insert the image at any index
// attributedString.insertAttributedString(NSAttributedString(attachment:attachment), atIndex: 0)
label.attributedText = attributedString

Resources