简体   繁体   中英

unable trigger uiview.animate when placed inside a function in swift

I am unable to trigger the animation, I put the function below outside the viewdidload function and created a custom function that will be trigger when the button is tapped. But instead of it creating the animation it gave me an error below. this is the error

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

this is the function that going to be triggered

@objc func triggeranimation(){
        UIView.animate(withDuration: 0.5, animations: {
            let intro:introViewController = introViewController()
            intro.Title.backgroundColor = UIColor.blue
        }, completion: nil)
    }

and I added button programmatically inside viewdidload that will trigger the function above. I try to put the custom func above before and after viewdidload function with the same error result. please help why is it telling me that it found nil when I clearly in the same view controller.

let nextBtn = UIButton(frame: CGRect(x:0, y: 0, width: 0, height: 0))
        nextBtn.translatesAutoresizingMaskIntoConstraints = false
        nextBtn.setTitle("Next", for: UIControlState.normal)
        nextBtn.backgroundColor = UIColor.blue
        nextBtn.addTarget(self, action: Selector("triggeranimation"), for: .touchUpInside)
        nextBtn.setTitleColor(UIColor.white, for: .normal)
        self.view.addSubview(nextBtn)
        // width cant change for some unknown reason
        nextBtn.widthAnchor.constraint(equalToConstant: 10)
        nextBtn.heightAnchor.constraint(equalToConstant: 20)
        nextBtn.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20).isActive = true
        nextBtn.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10).isActive = true

complete code

class introViewController: UIViewController{
    var Title:UILabel!
    var nextBtn:UIButton!

override func viewDidLoad() {
        super.viewDidLoad()
 let Title = UILabel(frame: CGRect(x: self.view.frame.size.width / 2, y: (self.view.frame.size.height + 30), width: 50, height: 10))
        Title.translatesAutoresizingMaskIntoConstraints = false
        Title.text = "WELCOME"
        Title.font = UIFont.systemFont(ofSize: 24, weight: .bold)
        Title.textAlignment = .center
        Title.textColor = UIColor.black
        self.view.addSubview(Title)
        Title.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -250).isActive = true
        Title.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true

let nextBtn = UIButton(frame: CGRect(x:0, y: 0, width: 0, height: 0))
        nextBtn.translatesAutoresizingMaskIntoConstraints = false
        nextBtn.setTitle("Next", for: UIControlState.normal)
        nextBtn.backgroundColor = UIColor.blue
        nextBtn.addTarget(self, action: Selector("triggeranimation"), for: .touchUpInside)
        nextBtn.setTitleColor(UIColor.white, for: .normal)
        self.view.addSubview(nextBtn)
        // width cant change for some unknown reason
        nextBtn.widthAnchor.constraint(equalToConstant: 10)
        nextBtn.heightAnchor.constraint(equalToConstant: 20)
        nextBtn.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20).isActive = true
        nextBtn.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10).isActive = true


}

@objc func triggeranimation(){
        UIView.animate(withDuration: 0.5, animations: {
            let intro:introViewController = introViewController()
            intro.Title.backgroundColor = UIColor.blue
        }, completion: nil)
    }
}

in addition, i also tried to move UIView.animate inside the viewdidload but it did not animate at all, it just change the color instantly.

UPDATE: i did solve the found nil problem, by changing Title variable var Title:UILabel! into var Title:UILabel! = UILabel() var Title:UILabel! = UILabel()

but i still have a problem with animation, it did not make any animation just instantly change the color even when i make the DURATION longer into 5.0

The problem is that intro is a newly initialized view controller which is completely unrelated to the instance in question. For example, viewDidLoad will not be called on that new instance. Instead, you just want to use "self", meaning THE loaded view controller.

@objc func triggeranimation(){
    UIView.animate(withDuration: 0.5, animations: {
        //let intro:introViewController = introViewController()
        self.Title.backgroundColor = UIColor.blue
    }, completion: nil)
}

There also seems to be a problem in your viewDidLoad code, where you are trying to initialize the Title and nextBtn properties. Instead, you are accidentally creating a local constant of the same name. This is why your properties are nil.

 // You have this now, which creates a local constant
 //let Title = UILabel(.. 

 // You want this instead, which initializes your property
 self.Title = UILabel(.. 

Do the same for nextBtn, of course.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM