Search code examples
iosswiftuiimageviewuitextviewnsattributedstring

Image followed by Text in vertical list format using a UITextView


I have a tableView in which cells are loaded with a list.For example a current cell may be a solid colored background with a list on it like this

Milk
Eggs
Tomatoes

The list is being filled from a data source so the amount to be placed in each cell is unknown. I am currently doing it using a UITextView as follows.

var joinedArray = [String]()
cell.textView.text = joinedArray.joined(separator: "\n")

I want to add pictures to the left of the word on each row. So for example I would have

"milk picture" Milk 
"EGGS Picture" Eggs 
"Tomatoes Pic" Tomatoes 

If I have a second array of the pictures, would it be possible to add them into the UITextView before each word (at the beginning of each line break) using attributed Strings or attachments.Something like what is done here.


Solution

  • would it be possible to add [UIImage] into the UITextView before each word?

    Yes but..., by default a UITableViewCell has an Image View that appears to the left of the default label.

    https://developer.apple.com/documentation/uikit/uitableviewcell/1623270-imageview

    In your tableView(_:cellForRowAt:) set the cells ImageView's image to your particular image based on the cell title:

    ...
    //Image of milk in xcassets.images.
    cell.imageView.image = UIImage(named: "milk.png")!
    // or from your array of images:
    cell.imageView.image = 
    ...
    

    Otherwise I recommend creating a custom tableViewCell programmatically or in interface builder. A google search for "custom table view cell" pulled up a number of resources.

    If you still want to add it to the attributed text of a UITextView you can create a for loop to loop over the elements in your arrays and generate the attributed text, assuming you have an image array and each image has a corresponding text i.e. each array is the same length:

    func generateTextFrom(_ images:[UIImage], text:[String]) -> NSMutableAttributedString {
        let fullText = NSMutableAttributedString(string: "")
    
        for i in 0..<text.count {
            // Create our NSTextAttachment to attach the image
            let imageAttachment = NSTextAttachment()
            imageAttachment.image = images[i]
    
            // wrap the attachment in its own attributed string so we can append it
            let imageString = NSAttributedString(attachment: imageAttachment)
    
            // Then, the text
            let textItem = NSAttributedString(string: text[i])
    
            //Then append the text to image, then to fullText
            fullText.append(imageString)
            fullText.append(textItem)
            fullText.append(NSAttributedString(string: "\n"))
        }
    
        // finally set the textview's attributed text.
        return fullText
    }
    

    View Hierarchy