Robert Constantinescu
Robert Constantinescu

Reputation: 349

iOS Swift - Function from other class doesn't run

I want to create a class with a blurred view that should appear on the existing view if any problems occurred. Here is the code:

import Foundation
import UIKit

class checkProblems{

    let effectView:UIVisualEffectView = UIVisualEffectView (effect: UIBlurEffect(style: UIBlurEffectStyle.Light))
    var view: UIView
    let label = UILabel()
    let retry = UIButton()

    init(view: UIView){
        self.view = view
        self.check()
    }

    func check(){
        effectView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
        label.frame = CGRectMake(0, (self.view.frame.height/2)-20, self.view.frame.width, 40)
        label.text = "Server connection problems."
        label.textAlignment = NSTextAlignment.Center
        label.textColor = UIColor.darkGrayColor()
        label.font = UIFont (name: "HelveticaNeue-Light", size: 20)

        retry.frame = CGRectMake(0, (self.view.frame.height/2)+10, self.view.frame.width, 40)
        retry.setTitle("Tap here to retry.", forState: UIControlState.Normal)
        retry.addTarget(self, action: "pressed:", forControlEvents: .TouchUpInside)

        self.view.addSubview(effectView)
        effectView.addSubview(label)
        effectView.addSubview(retry)
    }

    func pressed(sender: UIButton!){
       println("here")
    }
}

And this is how I call it on the view controller:

let checkObject = checkProblems(view: view)

Everything works fine until I press the button "Tap here to retry". Then, my app crashes.

Upvotes: 0

Views: 159

Answers (1)

gutenmorgenuhu
gutenmorgenuhu

Reputation: 2362

I think you break the MVC-Pattern with your approach. Followed by problems with the corresponding references for the addAction method. Please add all view-creating or -alternating code to the viewController. This will make your app a lot easier to understand. I changed your code to correctly implement the MVC-Pattern (and making it runnable altogether)

import UIKit

class ViewController: UIViewController {

  let effectView:UIVisualEffectView = UIVisualEffectView (effect: UIBlurEffect(style: UIBlurEffectStyle.Light))
  let label = UILabel()
  let retry = UIButton()

  override func viewDidLoad() {
    super.viewDidLoad()        
    check()
  }

  func check(){
    effectView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
    label.frame = CGRectMake(0, (self.view.frame.height/2)-20, self.view.frame.width, 40)
    label.text = "Server connection problems."
    label.textAlignment = NSTextAlignment.Center
    label.textColor = UIColor.darkGrayColor()
    label.font = UIFont (name: "HelveticaNeue-Light", size: 20)

    retry.frame = CGRectMake(0, (self.view.frame.height/2)+10, self.view.frame.width, 40)
    retry.backgroundColor = .blueColor()
    retry.setTitle("Tap here to retry.", forState: UIControlState.Normal)
    retry.addTarget(self, action: "pressed:", forControlEvents: UIControlEvents.TouchUpInside)

    effectView.addSubview(label)
    effectView.addSubview(retry)
    view.addSubview(effectView)    
  }
  func pressed(sender: UIButton){
    println("here")
  }
}

In addition to your comment, I show you an example of a MVC-conserving approach, which will subclass UIViewController. You can then load your checkProblems class with presentViewController:

Code from the calling VC:

import UIKit    
  class ViewController: UIViewController {
    override func viewDidLoad() {
      super.viewDidLoad()
        }
    override func viewDidAppear(animated: Bool) {
      super.viewDidAppear(animated)
      let checkProblemsVC = CheckProblemsViewController()
      presentViewController(checkProblemsVC, animated: true, completion: nil)
    }
  }

And the new subclassed CheckProblemsViewController:

    import UIKit

class CheckProblemsViewController: UIViewController {

  let effectView:UIVisualEffectView = UIVisualEffectView (effect: UIBlurEffect(style: UIBlurEffectStyle.Light))
  let label = UILabel()
  let retry = UIButton()

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    check()
  }

  func check(){
    effectView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
    label.frame = CGRectMake(0, (self.view.frame.height/2)-20, self.view.frame.width, 40)
    label.text = "Server connection problems."
    label.textAlignment = NSTextAlignment.Center
    label.textColor = UIColor.darkGrayColor()
    label.font = UIFont (name: "HelveticaNeue-Light", size: 20)

    retry.frame = CGRectMake(0, (self.view.frame.height/2)+10, self.view.frame.width, 40)
    retry.backgroundColor = .blueColor()
    retry.setTitle("Tap here to retry.", forState: UIControlState.Normal)
    retry.addTarget(self, action: "pressed:", forControlEvents: UIControlEvents.TouchUpInside)

    effectView.addSubview(label)
    effectView.addSubview(retry)
    view.addSubview(effectView)

  }

  func pressed(sender: UIButton){
    println("here")
  }


}

Upvotes: 1

Related Questions