Search code examples
swiftuiviewuiscrollviewautolayoutuiimageview

Autolayout UIScrollView with a content view and UIImageView not sizing properly


I'm having some problems with the UIView where all content is added as subviews (ALLES_SAMEN_VIEW). I've added some borders so you can see where it's going wrong.

I'm adding all my views as subviews to my content view because they need to overlap and can zoom togethor. The content view is not stretched in width/height as the UIImageView and my custom subclass of UIView for drawing. What is weird because everything is inside of the content view.

Because of this my touchHandler is only being recognized in the smaller not streched view aka "ALLES_SAMEN_VIEW" and not further. This should be stretched like all the rest to work proper. Still I can draw further then the border of the content view if i start in the content view.

Thanks in advance!

var afbeelding = UIImage()
var drawView = DrawingCanvas()
var imageView = UIImageView()

@IBOutlet var ALLES_SAMEN_VIEW: UIView!

@IBOutlet var scrollView: UIScrollView!
@IBOutlet var EraserButtonOutlet: UIBarButtonItem!

override func viewDidLoad() {
    super.viewDidLoad()
    scrollView.delegate = self
    
    imageView = UIImageView(image: afbeelding) //Setting image of user as background
    
    scrollView.contentSize = afbeelding.size //Setting size of image as contentsize for scrollview
    
    scrollView.panGestureRecognizer.minimumNumberOfTouches = 2 // 2 finger panning and zooming. 1 is for drawing
    scrollView.panGestureRecognizer.maximumNumberOfTouches = 2
    
    drawView.frame = imageView.frame // Everything should have the same frame size etc
    ALLES_SAMEN_VIEW.frame = imageView.frame

    drawView.isOpaque = false // false otherwise it's not transparant as top view
    
    ALLES_SAMEN_VIEW.addSubview(imageView) // Adding all in the same view for zooming at the same time
    ALLES_SAMEN_VIEW.addSubview(drawView)
    
    scrollView.addSubview(ALLES_SAMEN_VIEW) // Adding the contentview to the scrollview

    drawView.dag = dag // Setting object in custom view for handeling the lines
    
    /*Testing
     ImageView for background image
     DrawView where user can draw on the background image (Custom class for storing everything)
     ALLES_SAMEN_VIEW for putting the 2 as subview so the zoom would be the same
     */
    
    ALLES_SAMEN_VIEW.layer.borderColor = UIColor.black.cgColor
    ALLES_SAMEN_VIEW.layer.borderWidth = 10
    
    scrollView.layer.borderColor = UIColor.blue.cgColor
    scrollView.layer.borderWidth = 2
    
    drawView.layer.borderColor = UIColor.red.cgColor
    drawView.layer.borderWidth = 15
    
    imageView.layer.borderColor = UIColor.yellow.cgColor
    imageView.layer.borderWidth = 20
    
    setZoomScale()
}

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    return ALLES_SAMEN_VIEW
}

func setZoomScale() {
    var minZoom = min(self.view.bounds.size.width / ALLES_SAMEN_VIEW.bounds.size.width, self.view.bounds.size.height / ALLES_SAMEN_VIEW.bounds.size.height);

    if (minZoom > 1.0) {
        minZoom = 1.0;
    }

    scrollView.minimumZoomScale = minZoom;
    scrollView.zoomScale = minZoom;
    scrollView.maximumZoomScale = 8.0
}

Constraints:

Example Storyboard Constraints Constraints2


Solution

  • I made the following changes in your code, and it appears that the ALLES_SAMEN_VIEW now has the correct frame:

    1. Declare your imageView variable this way: (instead of var imageView = UIImageView())
    @IBOutlet var imageView: UIImageView!
    

    Then add a UIImageView in the Storyboard as a subview of ALLES_SAMEN_VIEW. Make sure you also add constraints to make this view the same size as ALLES_SAMEN_VIEW.

    1. remove these lines: (let the storyboard handle this)
    ALLES_SAMEN_VIEW.addSubview(imageView)
    ...
    scrollView.addSubview(ALLES_SAMEN_VIEW)
    
    1. replace this line:
    imageView = UIImageView(image: afbeelding)
    

    with this:

    imageView.image = afbeelding
    

    NOTES:

    • if you want to programmatically add the subviews (as you originally did), you also need to programmatically add constraints to make the frames match. But since you are already using the storyboard, you might as well let it handle these relationships
    • these changes don't make the drawView correctly sized: you will probably also want to instantiate the drawView using the storyboard and add constraints, the same way I did with imageView
    • as I have it, the pinch zoom gesture probably isn't doing what you want, but that's outside the scope of your question, I think