iosswift3uiimageviewtextviewcatextlayer

add textview as a sublayer of an image ios swift


let ss = CATextLayer()
  ss.frame = rect
  ss.backgroundColor = UIColor.blue.cgColor
  ss.foregroundColor = UIColor.cyan.cgColor
  ss.string = mytextView.text
  myImage.layer.addSublayer(ss)

I am trying to add an editable textview as a sublayer of an imageview.the problem is, i am not able to edit and also not able to add gesture recognisers for this textlayer. How can i make this textlayer do exactly what a textview does.


Solution

  • Just use UITextView or UITextField and add it as subview to the UIImageView, something like:

    let textView = UITextView()
    //configure text view like you want
    //add constraints or size it as you want
    myImage.addSubview(textView)
    

    Remember UIImageView is just another subclass of UIView so you can add subviews to it like for a regular UIView.


    Going on to what you are dealing with, since some of the views you add are CALayers and some will be UIViews or subclasses of both (for instance UITextView is UIView subclass)

    I would add two properties to your class:

    var addedViews = [Any]()
    var undoStack = [Any]()
    

    I know this is not very Swift like since you can put anything into these two arrays but still.

    Then when you create a new layer or view you also add it to addedViews array:

    let layer = CAShapeLayer()
    layer.frame = CGRect(x: 30, y: 30, width: 100, height: 100)
    layer.backgroundColor = UIColor.red.cgColor
    layer.transform = CATransform3DMakeRotation(0.2, 0, 0, 1)
    addedViews.append(layer)
    

    So addedViews array will hold references to all the views you added, so when you undo you can do just the following:

    if let viewLayer = addedViews.last {
        if let view = viewLayer as? UIView {
            view.removeFromSuperview()
        } else if let layer = viewLayer as? CALayer {
            layer.removeFromSuperlayer()
        }
    
        undoStack.append(viewLayer)
        addedViews.removeLast()
    }
    

    If you then want to redo the change you do the same thing but you get the last view from undoStack like so:

    if let viewLayer = undoStack.last {
        if let view = viewLayer as? UIView {
            self.view.addSubview(view)
        } else if let layer = viewLayer as? CALayer {
            view.layer.addSublayer(layer)
        }
    
        addedViews.append(viewLayer)
        undoStack.removeLast()
    }