Ja5onHoffman
Ja5onHoffman

Reputation: 672

UILabel text isn't updated when modal re-appears

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

Answers (1)

luk2302
luk2302

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

Related Questions