Search code examples
iosuitableviewswiftuiscrollviewcontentsize

Setting content size of UIScrollView to its frame width when UIScrollView is located in a Custom UITableViewCell


I have added a UIScrollView to a custom UITableViewCell.

I designed the cell and added the scrollview in my storyboard and set the constraints there. The cell and the scrollview's frame are displaying correctly.

However, I do not want my scrollview to scroll horizontally, so I want to set the contentSize.width property to the width of the scroll view's frame. I am setting my code for this inside my custom UITableViewCell class' awakeFromNib method.

The problem is that this method is apparently called before the frame's width is adjusted to fit the current size device, so I am getting the width to be the width in the storyboard, which is too long.

I have seen online that the methods viewDidLoad and viewDidLayoutSubviews are called after the sizes are adjusted, but these are methods inside the UIViewController class. They do not appear to be a part of the UITableViewCell class.

I do not know how to get a reference to every custom cell inside the UIViewController in order to set the values in the suggested methods.

Can someone tell me how to do this, or where I can put this code inside the UITableViewCell class? Thanks!

Here is my UITableViewCell class for reference.

import UIKit

class CustomTableViewCell: UITableViewCell, UIScrollViewDelegate {


    @IBOutlet weak var winLoseValueLabel: UILabel!
    @IBOutlet weak var dateLabel: UILabel!
    @IBOutlet weak var newTotalLabel: UILabel!
    @IBOutlet weak var locationLabel: UILabel!
    @IBOutlet weak var playersScrollView: CustomTableCellScrollView!
    @IBOutlet weak var scrollContentView: UIView!

    var numLinesInScrollView : CGFloat?
    var tblView : UITableView?
    var people : String?


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        self.playersScrollView.tblView = tblView
        numLinesInScrollView = 0.0
        self.playersScrollView.contentSize.width = self.scrollContentView.frame.width
        self.playersScrollView.contentSize.height = 100
        self.playersScrollView.backgroundColor = UIColor(red: 1.0, green: 1.0, blue: 0, alpha: 0.25)
        self.playersScrollView.addSubview(self.scrollContentView)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        //self.playersScrollView.contentSize.width = self.playersScrollView.frame.size.width
        /*****Updating the contentSize did not work in this method either*****/
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
    }
}

Here is the View Controller.

import UIKit

class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tblView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.    
    }

    override func viewDidLayoutSubviews(){
        super.viewDidLayoutSubviews() 
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataMgr.data.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell : CustomTableViewCell = self.tblView.dequeueReusableCellWithIdentifier("ledgerCell", forIndexPath : indexPath) as! CustomTableViewCell

        var values = dataMgr.data[indexPath.row]
        cell.newTotalLabel?.text = "\(values.newTotal)"
        cell.winLoseValueLabel?.text = "\(values.newTotal - values.currentTotal)"
        cell.dateLabel?.text = "5/17/2015"
        //cell.playersScrollView.contentSize.width = cell.playersScrollView.frame.width
        /*****Adjusting contentSize did not work here either*****/
        cell.tblView = self.tblView

        return cell
    }

}

Solution

  • I came up with a solution that works. Instead of setting the contentSize based on the frame's width, I set it based on the window's width and the distance on either side from the scrollview frame to the window's bounds. This solution allows the code to be placed in the awakeFromNib() method of the CustomTableViewCell class.

    self.playersScrollView.contentSize.width = UIScreen.mainScreen().bounds.width - (self.playersScrollView.frame.minX * 4)
    

    The only thing I don't understand is why I had to multiply the distance between the window bounds and the scrollview's frame by 4 rather than 2. I have the same width on both sides of the scrollview, but multiplying by 2 gave incorrect values, while multiplying by 4 gave correct values on all screen sizes.