Reputation: 672
I've created a reusable modal UIView as a singleton object, but am having trouble changing the text of a label it contains. When the modal appears a second time, the new text appears over the old text. I'm guessing this is due to the fact that the label is only instantiated once? If so, then why can I add text but not remove it? Here's the code:
class TransparentModal: UIView {
static let modal = TransparentModal()
class func modalInView(view: UIView, forSelectionOrPlacement: String) -> TransparentModal {
let f = CGRectMake(0, view.bounds.size.height, view.bounds.size.width, view.bounds.size.height)
modal.frame = f
modal.alpha = 0.7
modal.backgroundColor = UIColor.darkGrayColor()
let button = UIButton(frame: CGRectMake(0, 0, 116, 50))
button.center = CGPointMake(view.bounds.size.width / 2, view.bounds.size.height / 1.6)
button.backgroundColor = UIColor.lightGrayColor()
button.layer.cornerRadius = 4
button.setTitle("Ok", forState: UIControlState.Normal)
button.addTarget(self, action:"dismiss:", forControlEvents: UIControlEvents.TouchUpInside)
modal.addSubview(button)
let label = UILabel(frame: CGRectMake(0, 0, 260, 100))
label.center = CGPointMake(view.bounds.size.width / 2, view.bounds.size.height / 3)
label.numberOfLines = 0
label.text = ""
// This is where I'm going wrong
if forSelectionOrPlacement == "selection" {
label.text = "" // Attempting to remove previous text
label.text = "Text for condition one."
} else if forSelectionOrPlacement == "placement" {
label.text = ""
label.text = "Text for condition two."
}
modal.addSubview(label)
view.addSubview(modal)
self.animateWithDuration(0.5, animations: { () -> Void in
self.modal.frame.origin.y -= view.bounds.size.height
})
return modal
}
class func dismiss(sender: UIButton) {
self.animateWithDuration(0.2, animations: { () -> Void in
self.modal.alpha = 0
}) { (Bool) -> Void in
self.modal.removeFromSuperview()
}
}
}
I know this is a bit of a convoluted way to create a simple modal. It was more an exercise in creating a reusable object. The modal also needs to appear over other modal views, views with no navigation controller, etc., so I wanted to try to make something flexible.
Update: Below answer is correct except that variables can only be added as static
to the class. Removing the label in the dismiss
function allows the label to be re-instantiated with new text at the modal's next appearance.
Upvotes: 0
Views: 92
Reputation: 57114
As kursus wrote in a comment: you do not remove the button and the label as subviews from their parentView (the actual modal view). If it will be presented again two new instances will be created and positioned over the previous ones. I guess you only see the label because they are basically transparent, the buttons overlay completely.
To fix it add two variables to your class:
var button:UIButton!
var label:UILabel!
and then change two lines in modalInView
to
if label == nil {
label = UILabel(frame: CGRectMake(0, 0, 260, 100))
}
and
if button == nil {
button = UIButton(frame: CGRectMake(0, 0, 116, 50))
}
That will cause the button and label to only be created if they have not been created before.
Another way would be to remove the two views in the success
block of your dismiss
function like
self.animateWithDuration(0.2, animations: { () -> Void in
self.modal.alpha = 0
}) { (Bool) -> Void in
self.modal.removeFromSuperview()
button.removeFromSuperview()
label.removeFromSuperview()
}
Upvotes: 2