Linus Bicker
Linus Bicker

Reputation: 129

swift delegate variable is always nil

I'm a relatively new developer and have used protocols/delegates fairly regularly but I am stuck on getting this one to implement properly. I have a view within my view controller that is assigned a class for a StarRatingView. I need to capture within the viewcontroller class the float value that the StarRatingView generates.

The star rating is working fine. I'm just not able to set the delegate variable for some reason.

here's where I define the protocol and the delegate variable.

protocol StarRatingProtocol {
    func receiveStarRating(_ touchedStarRating: Float)
}



@IBDesignable
class StarRatingView: UIView {
    
    var delegate: StarRatingProtocol?  //THIS IS ALWAYS NIL NOT GETTING SET
    

Here's where I call the delegate function

    

fileprivate func touched(touch: UITouch, moveTouch: Bool) {
    
        guard !moveTouch || lastTouch == nil || lastTouch!.timeIntervalSince(Date()) < -0.1 else { return }
        print("processing touch")
        guard let hs = self.hstack else { return }
        let touchX = touch.location(in: hs).x
        let ratingFromTouch = 5*touchX/hs.frame.width
        var roundedRatingFromTouch: Float!
        switch starRounding {
        case .roundToHalfStar, .ceilToHalfStar, .floorToHalfStar:
            roundedRatingFromTouch = Float(round(2*ratingFromTouch)/2)
        case .roundToFullStar, .ceilToFullStar, .floorToFullStar:
            roundedRatingFromTouch = Float(round(ratingFromTouch))
        }
        self.rating = roundedRatingFromTouch
        lastTouch = Date()
        
        guard delegate != nil else {return} 
        
        delegate!.receiveStarRating(roundedRatingFromTouch)
}



This is my view controller class where I set the protocol and try to set the delegate value . Should I be setting the delegate value somewhere other than viewdidload?



class LogController: UIViewController, StarRatingProtocol {
  

    @IBOutlet weak var starRatingView: StarRatingView!
    @IBOutlet weak var labelStarRating: UILabel!
    
    let starRating = StarRatingView()
    var testRating: Float?
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

   
        starRating.delegate = self
    }


Upvotes: 0

Views: 618

Answers (1)

matt
matt

Reputation: 535212

The problem is that when you say let starRating = StarRatingView(), that is a new and different StarRatingView that you are creating right now. That's not what you want; you want the StarRatingView that already exists in the interface. Presumably, if the outlet is hooked up properly, that would be self.starRatingView. That is the StarRatingView whose delegate you need to set.

Another (unrelated) problem is that the delegate needs to be weak. Otherwise there will be a retain cycle and a memory leak.

Upvotes: 2

Related Questions