Daniel Daniel - 3 months ago 12
Swift Question

How to Refer to a Subview Button of Custom UIView in UITableViewController

I'm facing problems with UITableViewCell being reused, and I am receiving suggestions to make the action of a UIButton occur within the UITableViewController.
The problem is that because the UIButton is instantiated within the custom UIView subclass, I cannot find a way to refer to it.

The code is:

class StarButton: UIView {

var buttonRow : Int = 0
var buttonSelected : Bool = false

override init (frame : CGRect)
{
super.init(frame : frame)
initStar()
}

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

func initStar(){

let filledStarImage = UIImage(named: "filledStar")
let emptyStarImage = UIImage(named: "emptyStar")

let button = UIButton(frame: CGRect(x: 2, y: 2, width: 33, height: 33))

button.userInteractionEnabled = true
button.addTarget(self, action: #selector(StarButton.fillingStar(_:)), forControlEvents: UIControlEvents.TouchUpInside)

button.setImage(emptyStarImage, forState: .Normal)
button.setImage(filledStarImage, forState: .Selected)

if buttonSelected == true{
button.selected = true
}

addSubview(button)
}

//Could have various errors
func fillingStar(sender: UIButton){
if (sender.selected) == false{
FavoritesManager.favoritesList.setObject(ChemQuizCollection.wordListObject.quizList[buttonRow], forKey: "\(buttonRow)")
sender.selected = !sender.selected
FavoritesManager.favoritesList.synchronize()
} else{
FavoritesManager.favoritesList.removeObjectForKey("\(buttonRow)")
sender.selected = !sender.selected
FavoritesManager.favoritesList.synchronize()
}

}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
for view in subviews
{
view.touchesBegan(touches, withEvent: event)
}
}

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool
{
return true
}


}

This is the custom UIView subclass. I want to refer to the "button" in func initStar().
Using
for subview in instantiatedStarButton.subviews{
subview.selected = true
}
throws an error saying UIView doesn't have member "selected". Is there a better way?

Thank you all in advance.

Answer

The problem is with your code

StarButton.subviews{ subview.selected = true }

.subviews give UIView not UIButton: UIView has no .selected property

What should be done is following code or something similar. You have to cast tour UIView to UIButton

let filtured  =  instantiatedStarButton.subviews.filter({
            if let button = $0 as? UIButton{
                return button.selected
            }
            return false
        })