How to display from UILabel HTML content from API such as images and video, expect text which I have already done it. Is there a way to fetch from UILabel without using textview or WebKit all the content.
My code is kinda working from the images but the images are huge/cut and also doesn't embed videos from YT or FB
https://imgur.com/a/zdaMCHv
do {
if let htmlMessageData = post?.content.data(using:
String.Encoding.utf16) {
let layoutMessage = try NSMutableAttributedString(data:
htmlMessageData, options:
[NSAttributedString.DocumentReadingOptionKey.documentType:
NSAttributedString.DocumentType.html], documentAttributes: nil)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .justified
layoutMessage.addAttribute(NSAttributedString.Key.paragraphStyle,
value: paragraphStyle, range: NSRange(location: 0, length:
layoutMessage.string.count))
self.contentLabel.attributedText = layoutMessage
}
}
catch {}
Related
I am trying to convert a UIImage to a SwiftUI Image using the init(uiImage:) initializer. My UIImage itself is created from a CIImage generated by a CIQRCodeGenerator CIFilter. I am running my code on a Playground in Xcode 11.1 GM seed 1. Here is the entirety of my code:
import SwiftUI
import UIKit
func qrCodeImage(for string: String) -> Image? {
let data = string.data(using: String.Encoding.utf8)
guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
qrFilter.setValue(data, forKey: "inputMessage")
guard let ciImage = qrFilter.outputImage else { return nil }
let uiImage = UIImage(ciImage: ciImage)
let image = Image(uiImage: uiImage)
return image
}
let image = qrCodeImage(for: "fdsa")
And here is the result:
Even when I transform the image with CGAffineTransform(scaleX: 10, y: 10), the resulting SwiftUI Image at the end is still the same size, but blank.
Following solution provided in: Generating QR Code with SwiftUI shows empty picture
Here is the code:
var ciContext = CIContext()
func qrCodeImage(for string: String) -> Image? {
let data = string.data(using: String.Encoding.utf8)
guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
qrFilter.setValue(data, forKey: "inputMessage")
guard let ciImage = qrFilter.outputImage else { return nil }
let cgImage = ciContext.createCGImage(ciImage, from: ciImage.extent)
let uiImage = UIImage(cgImage: cgImage!)
let image = Image(uiImage: uiImage)
return image
}
let image = qrCodeImage(for: "fdsa")
Result:
screenshot in swift playground
Can confirm I encounter the same issue with a SwiftUI Image using a UIImage initialized from data. Can verify that the image is loaded when paused in debugging, but it does not display in the SwiftUI Image.
This solution worked for me: explicitly specify the image rendering mode. In my case I added the following: .renderingMode(.original)
#Eugene remark worked for me:
let image = Image(uiImage: uiImage).renderingMode(.original)
I have an image like this:
(Rendered as a template image)
I tried this code:
#IBOutlet weak var imgAdd: NSImageView!
imgAdd.layer?.backgroundColor = CGColor.white
Which only changes the background color of course.
Is there a way to change the color of this image programmatically?
So far I've tried the code below which doesn't work. (The image color doesn't change.)
func tintedImage(_ image: NSImage, tint: NSColor) -> NSImage {
guard let tinted = image.copy() as? NSImage else { return image }
tinted.lockFocus()
tint.set()
let imageRect = NSRect(origin: NSZeroPoint, size: image.size)
NSRectFillUsingOperation(imageRect, .sourceAtop)
tinted.unlockFocus()
return tinted
}
imgDok.image = tintedImage(NSImage(named: "myImage")!, tint: NSColor.red)
Swift 4
Updated answer for Swift 4
Please note, this NSImage extension is based on #Ghost108 and #Taehyung_Cho's answers, so a larger credit goes to them.
extension NSImage {
func tint(color: NSColor) -> NSImage {
let image = self.copy() as! NSImage
image.lockFocus()
color.set()
let imageRect = NSRect(origin: NSZeroPoint, size: image.size)
imageRect.fill(using: .sourceAtop)
image.unlockFocus()
return image
}
}
Swift 4 version
extension NSImage {
func image(withTintColor tintColor: NSColor) -> NSImage {
guard isTemplate else { return self }
guard let copiedImage = self.copy() as? NSImage else { return self }
copiedImage.lockFocus()
tintColor.set()
let imageBounds = NSMakeRect(0, 0, copiedImage.size.width, copiedImage.size.height)
imageBounds.fill(using: .sourceAtop)
copiedImage.unlockFocus()
copiedImage.isTemplate = false
return copiedImage
}
}
I found the solution with everyone's help:
(Swift 3)
func tintedImage(_ image: NSImage, tint: NSColor) -> NSImage {
guard let tinted = image.copy() as? NSImage else { return image }
tinted.lockFocus()
tint.set()
let imageRect = NSRect(origin: NSZeroPoint, size: image.size)
NSRectFillUsingOperation(imageRect, .sourceAtop)
tinted.unlockFocus()
return tinted
}
imgDok.image = tintedImage(NSImage(named: "myImage")!, tint: NSColor.red)
Important: in interface builder I had to set the "render as" setting of the image to "Default".
The other solutions don't work when the user wants to change between light and dark mode, this method solves that:
extension NSImage {
func tint(color: NSColor) -> NSImage {
return NSImage(size: size, flipped: false) { (rect) -> Bool in
color.set()
rect.fill()
self.draw(in: rect, from: NSRect(origin: .zero, size: self.size), operation: .destinationIn, fraction: 1.0)
return true
}
}
}
Be aware that if you use .withAlphaComponent(0.5) on an NSColor instance, that color loses support for switching between light/dark mode. I recommend using color assets to avoid that issue.
Had to modify #Ghost108's answer little bit for Xcode 9.2.
NSRectFillUsingOperation(imageRect, .sourceAtop)
to
imageRect.fill(using: .sourceAtop)
Thanks.
Since your image is inside an NSImageView, the following should work fine (available since macOS 10.14):
let image = NSImage(named: "myImage")!
image.isTemplate = true
let imageView = NSImageView(image: image)
imageView.contentTintColor = .green
The solution is to apply "contentTintColor" to your NSImageView instead of the NSImage.
See: Documentation
no need to copt:
extension NSImage {
func tint(with color: NSColor) -> NSImage {
self.lockFocus()
color.set()
let srcSpacePortionRect = NSRect(origin: CGPoint(), size: self.size)
srcSpacePortionRect.fill(using: .sourceAtop)
self.unlockFocus()
return self
}
}
Since you can't use the UIImage functions, you can try using CoreImage (CI). I don't know if there is an easier version but this one will work fore sure!
First you create the CIImage
let image = CIImage(data: inputImage.tiffRepresentation!)
Now you can apply all kinds of filters and other stuff to the image, it's a really powerful tool.
The documentation for CI: https://developer.apple.com/documentation/coreimage
The Filter List: https://developer.apple.com/library/content/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html
Here is a simple filter example, you basically initialise a filter and then set the values for it, output it and repeat.
let yourFilterName = CIFilter(name: "FilterName")
yourFilterName!.setValue(SomeInputImage, forKey: kCIInputImageKey)
yourFilterName!.setValue(10, forKey: kCIInputRadiusKey)
let yourFilterName = yourFilterName!.outputImage
Now you can just convert the output back as NSImage.
let cgimg = context.createCGImage(yourFilterName!, from: yourFilterName!.extent)
let processedImage = NSImage(cgImage: cgimg!, size: NSSize(width: 0, height: 0))
Try this code it helps.
Swift 3
let theImageView = UIImageView(image: UIImage(named:"foo")!.withRenderingMode(.alwaysTemplate))
theImageView.tintColor = UIColor.red
UIImageView images are not loading either with downloading with Alamofire or using URL to convert to a data object and convert data object to a UIImage. My images on UITableViewCells are working but not the UIImageviews standalone in a UIView. It is giving me a blank.
UIImageViews: They are a subview of a UIView which is a subview of a UITableView
Here it is the code that Im using:
let imageURL = URL(string: _imageUrl)
let imageData = try? Data(contentsOf: imageURL!)
imageView.image = UIImage(data: imageData!)
Here is the extension that I'm using with Alamofire:
extension UIImageView {
func donwloadImageFrom(_ imageURL: String, contentMode: UIViewContentMode) {
let stringUrl = URL(string: imageURL)!
Alamofire.request(stringUrl, method: .get).response(completionHandler: { response in
if let imageData = response.data {
DispatchQueue.main.async(execute: {
self.contentMode = contentMode
self.image = UIImage(data: imageData)
})
}
})
}
}
I think the awakeFromNib() function bit changed.
I don't know exact reason but, after adding
layoutIfNeeded()
into awakeFromNib().
Made it works.
I'm trying to save images retrieved from Parse.com like this:
let userImageFile = object["Image"] as PFFile
userImageFile.getDataInBackgroundWithBlock {
(imageData: NSData!, error: NSError!) -> Void in
if error == nil {
image = UIImage(data:imageData)
let imageToSave:NSData = UIImagePNGRepresentation(image)
self.saveImage(intRandomNumb, retImage: imageToSave)
}
}
where the saveImage-function looks like this:
func saveImage(imagepath:Int, retImage:NSData){
println("image is being saved")
let defaults = NSUserDefaults.standardUserDefaults()
let imagePathName = "\(imagepath)"
defaults.setObject(retImage, forKey: imagePathName)
}
and later, I'm trying to display this image like this:
var point = gestureRecognizer.locationInView(self.tv)
if let indexPath = self.tv.indexPathForRowAtPoint(point)
{
let data = mainList[indexPath.row] as SecondModel
let fileRef = data.fileReference
let intFileRef = Int(fileRef)
println(intFileRef)
let defaults = NSUserDefaults.standardUserDefaults()
let usedKeyName = "\(intFileRef)"
if let photo = defaults.objectForKey(usedKeyName) as? UIImage {
println("Image created")
let photo = defaults.objectForKey(usedKeyName) as UIImage
var imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
imageView.image = photo
self.view.addSubview(imageView)
}
and the "Image created" never gets printed which means the retrieving somehow doesn't work.
I'm not quite sure if you're able to save images to the userdefaults like I've done here, but that was the best I could come up with, and I couldn't find any previous questions like this for Swift.
Any suggestions on how to proceed would be appreciated.
SOLUTION: The problem was that I tried to load the image directly as a UIImage. I also had to convert the NSData to a UIImage, this all happens in the last section of the code displayed above. Finally my code looks like this:
if let photo = defaults.objectForKey("\(intFileRef)") as? NSData {
println("Image created")
let photo = defaults.objectForKey("\(intFileRef)") as NSData
let imageToView:UIImage = UIImage(data: photo)
var imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
imageView.image = imageToView
self.view.addSubview(imageView)
}
I hope this can help others struggling with something similar to this.
Swift 3
Hey, try this beautiful code here:
Convert your UIImage to Data.
PNG:
yourDataImagePNG = UIImagePNGRepresentation(yourUIImageHere)
JPEG :
yourDataImageJPG = UIImage(data: yourUIImageHere,scale:1.0)
Save in UserDefaults.
UserDefaults().set(yourDataImagePNG, forKey: "image")
Recover from:
UserDefaults.standard.object(forKey: "image") as! Data
I hope to help!
It seems like you do not call defaults.synchronize() so it's not written to the defaults file.
I've got several UILabels with multiple lines of text, but the line spacing is larger than I would prefer. Is there any way to change this?
hi this is a late reply but it may help some one line height can be change change the text from plain to attribute
Since iOS 6, Apple added NSAttributedString to UIKit, making it possible to use NSParagraphStyle to change the line spacing.
To actually change it from NIB, please see souvickcse's answer.
Because I friggin hate using attributed text in interface builder (I always run into IB bugs), here is an extension to allow you to set line height multiple directly to a UILabel in interface builder
extension UILabel {
#IBInspectable
var lineHeightMultiple: CGFloat {
set{
//get our existing style or make a new one
let paragraphStyle: NSMutableParagraphStyle
if let existingStyle = attributedText?.attribute(NSAttributedString.Key.paragraphStyle, at: 0, effectiveRange: .none) as? NSParagraphStyle, let mutableCopy = existingStyle.mutableCopy() as? NSMutableParagraphStyle {
paragraphStyle = mutableCopy
} else {
paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 1.0
paragraphStyle.alignment = self.textAlignment
}
paragraphStyle.lineHeightMultiple = newValue
//set our text from existing text
let attrString = NSMutableAttributedString()
if let text = self.text {
attrString.append( NSMutableAttributedString(string: text))
attrString.addAttribute(NSAttributedString.Key.font, value: self.font, range: NSMakeRange(0, attrString.length))
}
else if let attributedText = self.attributedText {
attrString.append( attributedText)
}
//add our attributes and set the new text
attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
self.attributedText = attrString
}
get {
if let paragraphStyle = attributedText?.attribute(NSAttributedString.Key.paragraphStyle, at: 0, effectiveRange: .none) as? NSParagraphStyle {
return paragraphStyle.lineHeightMultiple
}
return 0
}
}