Search code examples
swiftuiviewuiviewcontrolleraddsubviewpresentviewcontroller

Adding subviews programmatically in presented view controller


Problem

Subview added programmatically to containerView ( UIView, which is connected with @IBOutlet on storyboard ) inside presented HistogramViewController (ViewController) is out of proper layout.

Code and comments

HistogramViewController

class HistogramViewController: UIViewController {
    
    @IBOutlet weak var containerView: UIView!
 
    var dataPoints: [[Int]]?
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .gray
      
        let chart_axes = ChartAxes(frame: containerView.frame)
        chart_axes.backgroundColor = UIColor.red.withAlphaComponent(0.6)
        containerView.addSubview(chart_axes)

    }

containerView has const values : 400 width , 600 hight set inside Storyboard's constraints

ChartAxes ( UIView added to containerView in HistogramVC )

extension HistogramViewController {
    
    private class ChartAxes : UIView{
        
        override func draw(_ rect: CGRect) {
            do{
               // self.backgroundColor = UIColor.clear.withAlphaComponent(0)
                let start = CGPoint(x:rect.origin.x,y:rect.origin.y)
                let joint = CGPoint(x:0,y:rect.height)
                let end = CGPoint(x:rect.width,y:rect.height)
                let axes = UIBezierPath()
                axes.move(to: start)
                axes.addLine(to: joint)
                axes.addLine(to: end)
                axes.lineWidth = 5.0
                UIColor.white.setStroke()
                axes.stroke()
            }
        }
    }

It's basically path from left-top corner, via left-bottom to right-bottom - like Axes in chart

Current result ( should not be like this ! )

Red area should be the same size as black containerView. Is it connected with function present(ViewController ) ?

   guard let controller = storyboard?.instantiateViewController(withIdentifier: "HistogramViewController") as? HistogramViewController else{ return }
           // controller.modalPresentationStyle = .overFullScreen
            present(controller,animated: true)

Result


Solution

  • Value of containerView.frame inside viewDidLoad is inaccurate Implement

    var chart_axes:ChartAxes!
    
    override func viewDidLayoutSubviews() {
       super.viewDidLayoutSubviews()
       chart_axes.frame = containerView.frame
    }
    

    OR set constraints in place

    let chart_axes = ChartAxes(frame: containerView.frame)
    chart_axes.backgroundColor = UIColor.red.withAlphaComponent(0.6)
    containerView.addSubview(chart_axes)   
    chart_axes.translatesAutoresizingMaskIntoConstraints = false 
    NSLayoutConstraint.activate([
      chart_axes.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
      chart_axes.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
      chart_axes.topAnchor.constraint(equalTo: containerView.topAnchor),
      chart_axes.bottomAnchor.constraint(equalTo: containerView.bottomAnchor) 
    ])