No image on custom UITableViewCell

122 Views Asked by At

I'm trying to make a custom UITableViewCell, that contains an image. And when the user scrolls the table up/down - here comes the parallax effect on table cells.

So, here's my code:

VEParallaxCell.swift:

import UIKit

class VEParallaxCell: UITableViewCell {

var parentTableView : UITableView?

var parallaxImage : UIImageView?

var parallaxRatio : CGFloat?

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {

    super.init(style: style, reuseIdentifier: reuseIdentifier)

    self.contentView.backgroundColor = UIColor.whiteColor()

    parallaxImage = UIImageView.new()
    self.contentView.addSubview(parallaxImage!)

    parallaxImage?.backgroundColor = UIColor.whiteColor()
    parallaxImage?.contentMode = UIViewContentMode.ScaleAspectFill

    self.clipsToBounds = true

    parallaxRatio = 1.5



}

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

override func willMoveToSuperview(newSuperview: UIView?) {

    super.willMoveToSuperview(newSuperview)

    var view : UIView = newSuperview!

    if view.isKindOfClass(UITableView) {

        parentTableView = view as? UITableView


    }

    view = view.superview!

    if (parentTableView != nil) {

        parentTableView?.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.New | NSKeyValueObservingOptions.Old, context: nil)

    }


}

override func removeFromSuperview() {

    super.removeFromSuperview()

    parentTableView?.removeObserver(self, forKeyPath: "contentOffset", context: nil)

    parentTableView = nil

}

override func layoutSubviews() {

    super.layoutSubviews()

    return

}



func setParallaxRatio(_parallaxRatio: CGFloat) {

    parallaxRatio = max(_parallaxRatio, 1.0)
    parallaxRatio = min(_parallaxRatio, 2.0)

    var rect : CGRect = self.bounds
    rect.size.height = rect.size.height * parallaxRatio!
    parallaxImage?.frame = rect

    updateParallaxOffset()

}

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {

    if keyPath == "contentOffset" {

        var array = [VEParallaxCell]()

        array = parentTableView?.visibleCells() as! [VEParallaxCell]

        if parallaxRatio == 1.0 || !contains(array, self) {

            return

        }

        updateParallaxOffset()

    }

}

func updateParallaxOffset() {

    var contentOffset : CGFloat = parentTableView!.contentOffset.y
    var cellOffset : CGFloat = self.frame.origin.y - contentOffset

    var percent : CGFloat = (cellOffset + self.frame.size.height) / (parentTableView!.frame.size.height + self.frame.size.height)

    var extraHeight : CGFloat = self.frame.size.height * (parallaxRatio! - 1.0)

    var rect : CGRect? = parallaxImage?.frame

    rect!.origin.y = -extraHeight * percent

    parallaxImage?.frame = rect!


}


override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}

And main view controller's cell creating method:

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

    var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! VEParallaxCell
    cell.parallaxImage?.image = UIImage(named: "eye.png")

    return cell
}

So, the problem is, that when I build and run the app, the compiler shows no errors and warnings, but when I add a new cell to my table, it adds it, but shows no image.

What should I do?

1

There are 1 best solutions below

2
On BEST ANSWER

Your image view's frame is probably (0, 0; 0, 0) (i.e. CGRectZero), making it impossible to see. You should be creating it like this instead:

parallaxImage = UIImageView( frame: self.bounds )

Also, your parallaxImage and parallaxRatio properties do not have to be optionals since you are defining them in an init method.

And to get the cell you're looking for in tableView:cellForRowAtIndexPath, you should be doing a conditional downcast:

if let cell = tableView.dequeueReusableCellWithIdentifier( "Cell", forIndexPath: indexPath) as? VEParallaxCell {
    cell.parallaxImage.image = UIImage(named: "eye.png")
    return cell
}
fatalError( "Unable to load cell of expected type 'VEParallaxCell'" )