Learn Courses My Dashboard

Text size in the text view

Hello.
I have the question about texts in the text view:
How can I define by code what are the sizes(I need mostly length, width possibly I will need) of the text and on which position does it end in the textView?
For instance, I have a text:
ABCDEFGH
IJKLMNOP.
I know that texts ends on the second string approximately 1.5 cm from the sentence:“For instance,…”.

What code do you have in your ViewController at the moment? Copy your code from your ViewController and paste it in as text in a reply.

Place 3 back-ticks ``` on the line above your code and 3 back-ticks ``` on the line below your code so that it is formatted nicely. The back-tick character is located on the same keyboard key as the tilde character ~ (below the Esc key).

This also makes it easier for anyone assisting as they can copy the code and carry out some testing.

import UIKit

struct KeyDefaults {
    static let keyTitle = "Title"
    static let keyNotes = "Note"
}

class EntryViewController: UIViewController, UITableViewDelegate {

    let defaults = UserDefaults.standard
    static let shared = EntryViewController()
    @IBOutlet var titleField: UITextField!
    @IBOutlet var textView: UITextView!
//    @IBOutlet weak var saveImage: UIImageView!
    let saveImage = UIImageView()
    let imagePicker = UIImagePickerController()
    public var noteTitle = ""
    public var texts = ""
    struct UserTexts: Codable {
        var titles: String
        var texts: String?
        var name: String {
            return "\(titles), \(texts ?? "")"
        }
    }

    public var txts:[UserTexts] {
        get {
            if let data = defaults.value(forKey: "txts") as? Data {
                return try! PropertyListDecoder().decode([UserTexts].self, from: data)
            } else {
                return [UserTexts]()
            }
        }
        set {
            if let data = try? PropertyListEncoder().encode(newValue) {
                defaults.set(data, forKey: "txts")
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: #selector(selectImage))
        
        titleField.becomeFirstResponder()
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapSave(gesture:)))
        tapGesture.numberOfTapsRequired = 1
        self.saveImage.isUserInteractionEnabled = true
        self.saveImage.addGestureRecognizer(tapGesture)
        titleField.text = defaults.string(forKey: KeyDefaults.keyTitle)
        textView.text = defaults.string(forKey: KeyDefaults.keyNotes)
        noteTitle = titleField.text!
        texts = textView.text
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "sicher", style: .done, target: self, action: #selector(sicher))
        
    }
    
    @objc func selectImage() {
        saveImage.frame = CGRect(x: 10, y: textView., width: textView.frame.size.width, height: 250)
        saveImage.contentMode = .scaleAspectFit
        saveImage.backgroundColor = .black
        textView.textContainer.exclusionPaths = [UIBezierPath(rect: saveImage.frame)]
        self.textView.addSubview(saveImage)
        saveImage.clipsToBounds = true
//        self.openImagePicker()
//        if let png = self.saveImage.image?.pngData() {
//            DBH.instance.saveImageinCoredata(at: png)
//        }
    }
    
    @objc func didTapSave(gesture: UITapGestureRecognizer) {//Verändern die Priorität!
        self.openImagePicker()
//        if let png = self.saveImage.image?.pngData() {
//            DBH.instance.saveImageinCoredata(at: png)
//        }
//        if let png = self.saveImage.image?.pngData() {//Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
//            let title = titleField.text!
//            let newText = textView.text!
//            if !title.isEmpty && !newText.isEmpty {
//                saveText(titles: title, texts: newText)
//                self.navigationController?.popViewController(animated: true)
//            } else {
//                exit(32)
//            }
//            DBH.instance.saveImageinCoredata(at: png)
//        }
//        else {
//            //was muß hier sein?
//        }
    }
    
    @objc func sicher() {
        if let png = self.saveImage.image?.pngData() {//Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
            let title = titleField.text!
            let newText = textView.text!
            if !title.isEmpty && !newText.isEmpty {
                saveText(titles: title, texts: newText)// hier muß sein etwa für erlauben User zu speichern eine Notiz ohne Foto sodas es wird kein SegFault Fehler, es muß sein bevor die saveText-Funktion Anrufen in die sicher-Funktion.
                DBH.instance.saveImageinCoredata(at: png)
                ViewController.share.indikator += 1//SS
                self.navigationController?.popViewController(animated: true)
            }
//            DBH.instance.saveImageinCoredata(at: png)
        }
    }
    
    func saveText(titles: String, texts: String) {
        let texte = UserTexts(titles: titles, texts: texts)
        txts.insert(texte, at: 0)
    }
    
}

extension EntryViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    
    func openImagePicker() {
        if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum) {
            imagePicker.delegate = self
            imagePicker.sourceType = .savedPhotosAlbum
            imagePicker.allowsEditing = false
            present(imagePicker, animated: true, completion: nil)
        }
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        dismiss(animated: true, completion: nil)
        if let img = info[.originalImage] as? UIImage {
            self.saveImage.image = img
        }
    }
}

In this code I made one mistake as to know where to fix the problem. But I don’t know which function or a chunk of code to use.

@Beginner

I’m not quite sure what you are trying to achieve here so if I go back to your previous question about how to add an imageView programatically, did you manage to get that working?

I’ve played around with your code and got the imageView frame to appear with a black background when you press the Camera button. Beyond that I have no idea what you are trying to do with that imageView.

(edit).
I just tapped on the imageView and managed to load an image into it from the photo library. Is that the intent?

Yes. It’s the intent. In this code you don’t need to know everything about my project. Just I don’t know how to place an imageView below the text that user will type, after user clicks the Camera button. For example


I type text here, and I want that after user hits the Camera button UIImageView will be placed straightly after text, and I want my app to place an image view straightly after text always. I need to place only one image in the text view.
Therefore, I need to define where a text ends or I need some chunk of code or some function for this.

OK I understand what you want to do. I configured the storyboard just about exactly the same as you have in the screenshot above. I don’t know how you are going to figure out where the text ends so that you can add the image immediately after it. The way the Constraints are configured will have to be tied to however you determine that location.

At the moment this is the code that adds the imageView to the textView but the position is at the bottom of the textView window and goes to the edges of the textView and is 250 points from top to bottom.

    @objc func selectImage() {
        saveImage.frame = CGRect(x: 0, y: textView.frame.height - 250, width: textView.frame.size.width, height: 250)
        saveImage.contentMode = .scaleAspectFit
        saveImage.backgroundColor = .black
        textView.textContainer.exclusionPaths = [UIBezierPath(rect: saveImage.frame)]
        self.textView.addSubview(saveImage)
        NSLayoutConstraint.activate ([
            saveImage.topAnchor.constraint(equalTo: textView.bottomAnchor, constant: -250),
            saveImage.bottomAnchor.constraint(equalTo: textView.bottomAnchor, constant: 0),
            saveImage.leadingAnchor.constraint(equalTo: textView.leadingAnchor, constant: 0),
            saveImage.trailingAnchor.constraint(equalTo: textView.trailingAnchor, constant: 0)
        ])
        saveImage.clipsToBounds = true

//        self.openImagePicker()
//        if let png = self.saveImage.image?.pngData() {
//            DBH.instance.saveImageinCoredata(at: png)
//        }
    }

That will not help. Ok, I understood that you don’t know. How did you create the Swift?!

I don’t understand your question.

You are one of the founders of the Swift, if you are Chris who makes some videos about development. Therefore I ask you this.

There are lots of Chrises.

Chris Parker is not Chris Ching (whose site this is) nor is he Chris Lattner (creator of the Swift language).

2 Likes

@Beginner

Yeah mate, I’m just a poor boy from a poor family.

If you are interested the following code is from a project I created to do basically what you wanted to do as far as placing an imageView on the screen. It does that by utilising a Long Press Gesture which is configured when the camera icon it tapped to allow you to long press on the screen where you want the imageView to appear. The position of the press is captured and the location y axis value dictates the top of the imageView position. The constraints then set the topAnchor, leadingAnchor, trailingAnchor and the bottomAnchor. After the imageView is in position a tap Gesture is attached to the imageView and when tapped triggers calling the image Picker to let the user select an image from the Photo Library.

The process:

  • Tap the camera icon
  • Long Press on the screen where you require the top of the imageView to be aligned to.
  • Tap on the imageView to select an image from the Photo Library

Hope that helps

import UIKit

class EntryViewController: UIViewController, UIGestureRecognizerDelegate {

    @IBOutlet weak var titleTextField: UITextField!
    @IBOutlet weak var myTextView: UITextView!
    var saveImage: UIImageView!
    var pressLocation: CGPoint = .zero
    var longPress = UILongPressGestureRecognizer()

    let imagePicker = UIImagePickerController()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        myTextView.backgroundColor = .systemGray5

        navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: #selector(configureLongPress))
    }

    @objc func configureLongPress() {
        longPress = UILongPressGestureRecognizer(target: self, action: #selector(recordLongPressPosition(gesture:)))
        longPress.minimumPressDuration = 1
        longPress.delegate = self
        myTextView.addGestureRecognizer(longPress)
        print("Tap Gesture configured")

    }

    @objc func recordLongPressPosition(gesture: UILongPressGestureRecognizer) {
        if gesture.state == .began {
            self.becomeFirstResponder()
            pressLocation = gesture.location(in: gesture.view)
            //  Remove the Long Press Gesture recogniser
            myTextView.removeGestureRecognizer(longPress)
            print(pressLocation.y)
            configureImageView()
        }
    }

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool{
        return true
    }

    func configureImageView() {
        saveImage = UIImageView()
        view.addSubview(saveImage)
        saveImage.frame = CGRect(x: 0, y: pressLocation.y, width: myTextView.frame.size.width, height: 250)
        myTextView.textContainer.exclusionPaths = [UIBezierPath(rect: saveImage.frame)]

        saveImage.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate ([
            saveImage.topAnchor.constraint(equalTo: myTextView.topAnchor, constant: pressLocation.y),
            saveImage.leadingAnchor.constraint(equalTo: myTextView.leadingAnchor, constant: 10),
            saveImage.trailingAnchor.constraint(equalTo: myTextView.trailingAnchor, constant: -10),
            saveImage.bottomAnchor.constraint(equalTo: myTextView.topAnchor, constant: pressLocation.y + 250)
        ])
        saveImage.backgroundColor = .black
        saveImage.contentMode = .scaleAspectFill
        saveImage.clipsToBounds = true
        configureSaveImageTapGesture()
    }

    func configureSaveImageTapGesture() {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapSave(gesture:)))
        tapGesture.numberOfTapsRequired = 1
        self.saveImage.isUserInteractionEnabled = true
        self.saveImage.addGestureRecognizer(tapGesture)
    }

    @objc func didTapSave(gesture: UITapGestureRecognizer) {
        openImagePicker()
    }

}

extension EntryViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {

    func openImagePicker() {
        if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum) {
            imagePicker.delegate = self
            imagePicker.sourceType = .savedPhotosAlbum
            imagePicker.allowsEditing = false
            present(imagePicker, animated: true, completion: nil)
        }
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        dismiss(animated: true, completion: nil)
        if let img = info[.originalImage] as? UIImage {
            self.saveImage.image = img
        }
    }
}

Thank you very much. I will look later. If you think that it’s a problem, it’s not. There are some worse situations, like if you wanted to do what do you like but you cannot do this because of some stupid causes or when you lost your talents and honor many times. That’s demotivate.