Home > Software engineering >  UIScrollVIew not Scrolling Vertically programatically no matter what
UIScrollVIew not Scrolling Vertically programatically no matter what

Time:08-16

I have been trying to scroll the view for a whole day yesterday and I am not able to figure out why it won't scroll. I am not sure what I am doing wrong !!

I have looked at the solutions on stackoverflow:

enter image description here

UPDATE:: Now the text scrolls, but when I add a UITableView in the UIView the scrolling works but the tableView is not seen in the UiView.

Is it due to the constraints again???

here is the code for the same::

class RecipeUIView: UIView, UITableViewDelegate, UITableViewDataSource{

    
    var currentRecipe: Receipe?
    
    private let tableView: UITableView = {
        let tableView = UITableView()

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
        
        tableView.backgroundColor = .green

        
        return tableView
    }()
    
    
    private var recipeTitle: UILabel! = {
        
        let label = UILabel()
        label.numberOfLines = 0
        label.font = .systemFont(ofSize: 24, weight: .bold)
        label.textColor = .gray
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
        label.adjustsFontForContentSizeCategory = true
        
        return label
    }()
    

    override init(frame: CGRect) {
        super.init(frame: frame)
            }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        
        print("     IngrediantsTableViewCell tableview count: \(currentRecipe?.ingredients.count ?? 0)")
        
        return currentRecipe?.ingredients.count ?? 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            
        print("     IngrediantsTableViewCell tableview cellForRow ")

        
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
            cell.textLabel!.text = "\(currentRecipe?.ingredients[indexPath.row].ingredient ?? "")"
            return cell

    }
    
    

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        //return UITableView.automaticDimension
        
        return 30

    }
    
    
    func setupView(currentRecipe: Receipe?){
        
        let margin = readableContentGuide
        
        
        self.currentRecipe = currentRecipe

        recipeTitle.text = currentRecipe?.dynamicTitle


        addSubview(recipeTitle)


        // Constraints

        recipeTitle.topAnchor.constraint(equalTo: margin.topAnchor, constant: 4).isActive = true
        recipeTitle.leadingAnchor.constraint(equalTo: margin.leadingAnchor, constant: 20).isActive = true
        recipeTitle.trailingAnchor.constraint(equalTo: margin.trailingAnchor, constant: -20).isActive = true

        addSubview(tableView)
        tableView.delegate = self
        tableView.dataSource = self
        
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.topAnchor.constraint(equalTo: recipeTitle.bottomAnchor, constant: 10).isActive = true
        tableView.leadingAnchor.constraint(equalTo: margin.leadingAnchor, constant: 20).isActive = true
        tableView.trailingAnchor.constraint(equalTo: margin.trailingAnchor, constant: -20).isActive = true

        tableView.bottomAnchor.constraint(equalTo: margin.bottomAnchor, constant: -20).isActive = true

        tableView.reloadData()
                
    }
    
    
}

CodePudding user response:

You are missing a constraint...

In your RecipeUIView class, you have this:

func setupView(currentRecipe: Receipe?){
    
    recipeTitle.text = currentRecipe?.dynamicTitle

    addSubview(recipeTitle)

    let margin = readableContentGuide
    
    // Constraints
    
    recipeTitle.topAnchor.constraint(equalTo: margin.topAnchor, constant: 4).isActive = true
    recipeTitle.leadingAnchor.constraint(equalTo: margin.leadingAnchor, constant: 20).isActive = true
    recipeTitle.trailingAnchor.constraint(equalTo: margin.trailingAnchor, constant: -20).isActive = true

}

So, you have no constraint controlling the view's Height.

Add this line:

    recipeTitle.bottomAnchor.constraint(equalTo: margin.bottomAnchor, constant: -20).isActive = true

And you'll get vertical scrolling.

Two side notes...

First, in ``RecipeViewController`, change your constraints like this:

NSLayoutConstraint.activate([
            
    scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
    scrollView.topAnchor.constraint(equalTo: view.topAnchor),
    scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            
    recipeView.leadingAnchor.constraint(equalTo: contentGuide.leadingAnchor),
    recipeView.topAnchor.constraint(equalTo: contentGuide.topAnchor),
    recipeView.trailingAnchor.constraint(equalTo: contentGuide.trailingAnchor),
    recipeView.bottomAnchor.constraint(equalTo: contentGuide.bottomAnchor),
            
    recipeView.widthAnchor.constraint(equalTo: frameGuide.widthAnchor),
            
])

There's no real functional difference, but it is more logical and more readable to think in terms of:

  • I'm constraining the scrollView to the view
  • I'm constraining the recipeView to the scroll view's .contentLayoutGuide (which determines the "scrollable" size)
  • I'm constraining the recipeView width the the scroll view's .frameLayoutGuide

Second, giving views contrasting background colors can be very helpful when trying to debug layouts.

For example, if I set background colors like this:

  • recipeTitle label : cyan
  • recipeView : yellow
  • scrollView : orange

It looks like this when running (with your original constraints):

enter image description here

Since the cyan label is a subview of the yellow view, it is obvious that the yellow view height is not correct.

After add the missing bottom constraint, it looks like this:

enter image description here

  • Related