Нажатие кнопки приводит к сбою всего приложения

В настоящее время я создаю пользовательский интерфейс приложения без использования IB или раскадровки. У меня есть следующая иерархия: 1. ViewController: который является основным контроллером представления. 2. DrawerViewController: контроллер представления для нижнего меню ящика. Контроллер основного представления добавляет в качестве подпредставления представление boxViewController. 3. Кнопка "Добавить": это кнопка UIB, созданная и программно добавленная к представлению BoxViewController.

Проблема в том, что, если я нажму на кнопку добавления, приложение вылетает, абсолютно ничего не выводя сообщения об ошибках, кроме (lldb).

Я пробовал следующее:

  1. Измените имя селектора и имя метода.
  2. Проверено имя метода селектора.
  3. Добавлен и удален параметр метода селектора.
  4. Изменено название кнопки.
  5. Добавлена ​​кнопка внутри другого вида.

Нет способа отследить ошибку, используя точки останова, потому что приложение компилируется очень хорошо, и приложение вылетает, только если вы нажимаете на кнопку.

Вот ссылка на тестовый проект, который я создал, чтобы показать проблему:

GitHub

ViewController:

class ViewController: UIViewController //, DrawerDelegate
{

//Lower Drawer.
var drawerView: DrawerView!

var drawerViewHidden: Bool = false
var addButton: UIButton!
var viewHeight: CGFloat! = 0
var viewWidth : CGFloat! = 0
var shownDrawerViewY: CGFloat!
var hiddenDrawerViewY: CGFloat!

init()
{
    super.init(nibName: nil, bundle: nil)
}

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



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

override func viewWillAppear(animated: Bool)
{
    super.viewWillAppear(animated);


}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


//MARK:- UI initialization.
/**
Private function that setsup the UI.
*/
private func setUpUI()
{
    setUpDrawer()
}

//MARK: Drawer setup.

/**
A private function that programatically creataes a drawer and add it to the view.
*/
private func setUpDrawer()
{
    var controller = DrawerViewController(width: self.view.frame.width, height: self.view.frame.height)

    self.view.addSubview(controller.view)
    //Hide
    // toggleDrawer()
}



//MARK:- Delegates.

//MARK: DrawerDelegate methods.
func addButtonClicked(sender: UIButton)
{
    //  toggleDrawer()
}   
}

DrawerViewController

class DrawerViewController: UIViewController
{
    //Drawer variables.
    var drawerViewHidden: Bool = false
    var addPinDrawer: AddPinDrawer!



    var viewHeight: CGFloat! = 0
    var viewWidth : CGFloat! = 0
    var shownDrawerViewY: CGFloat?
    var hiddenDrawerViewY: CGFloat?

    var addButton: UIButton?

    init(width: CGFloat, height: CGFloat)
    {
        super.init(nibName: nil, bundle: nil)

        viewWidth  = width
        viewHeight = height

        setUpUI()
    }

    override func viewDidLoad()
    {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

    }

    override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)


    }

    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    required override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
    {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    required init(coder aDecoder: NSCoder)
    {
        fatalError("init(coder:) has not been implemented")
    }


    //MARK:- UI setup
     func setUpUI()
    {
        setUpDimensions()
        setUpDrawerElements()
//        toggleDrawer()
    }

     func setUpDimensions()
    {
        //Determine the y in the case drawer is shown
        shownDrawerViewY  = viewHeight * 2.0/8.0

        //Determine the height of the drawer.
        let drawerHeight = viewHeight * 6.0/8.0

        //Determine the y in the case drawer is hidden
        hiddenDrawerViewY = viewHeight * 7.4/8.0

        //Create the frame, starting with the drawer shown.
        let frame = CGRectMake(0, shownDrawerViewY!, viewWidth, drawerHeight)
        //Create a new Drawer View.
        self.view = UIView(frame: frame)

        setUpAddButton(frame)



        //Setup the background image of the drawer.
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: Constants.drawerBackgroundImage)!)
    }

    func setUpDrawerElements()
    {
        //Setup the button.
        setUpAddPinDrawer()
    }

    func setUpAddPinDrawer()
    {
        addPinDrawer = AddPinDrawer(frame: CGRectMake(0, 0, self.view.frame.width, self.view.frame.height))
//        self.view.addSubview(addPinDrawer)
    }



    //MARK: Handling drawer toggles
    func toggleDrawer()
    {
        //Toggle the variable.
        drawerViewHidden = !drawerViewHidden

        //If the drawer must be hidden.
        if drawerViewHidden
        {
            hideDrawer()
        }

        //If the drawer must be shown
        else
        {
            showDrawer()
        }
    }

    func hideDrawer()
    {
        //Hide the drawer
        UIView.animateWithDuration(0.6, animations: { () -> Void in
            self.view.frame.origin.y = self.hiddenDrawerViewY!
        })
      //  drawerView.hideDrawer()
    }

    func showDrawer()
    {
        UIView.animateWithDuration(0.6, animations: { () -> Void in
            self.view.frame.origin.y = self.shownDrawerViewY!
        })
      //  drawerView.showDrawer()
    }


    func setUpAddButton(frame: CGRect!)
    {
        //Determine the button dimensions.
        let width:CGFloat = 75.0//1.0/10.0 * viewHeight
        let x = frame.width/2.0 - width/2.0

        //Button background image.
        let background = UIImage(named: Constants.addButtonBackgroundImage)!

        //Create the button.
        addButton = UIButton(frame: CGRectMake(x, -width/2.0, width, width)) as UIButton
//        addButton!.setImage(background, forState: UIControlState.Normal)

        addButton?.backgroundColor = UIColor.yellowColor()

        //Add the event handler.
        addButton!.addTarget(self, action: "buttonAdd:", forControlEvents: .TouchUpInside)


        //Set it rotated.
//        self.addButton!.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_4))


        //Add the button to the subview.
        self.view.addSubview(addButton!)

//        println(addButton!.targetForAction("test", withSender: addButton)!)
    }

    func buttonAdd(sender: UIButton)
    {
        println("Helloooo asdf")
    }
}

1 ответ

Решение

Я решил проблему. В инициализации DrawerViewController есть очень маленькая ошибка. В контроллере основного вида я создаю переменную с именем DrawerViewController и инициирую ее представление. Эта переменная будет освобождена после завершения метода, что означает, что все события не будут обработаны. Вызывает сбой приложения, поскольку нет метода для обработки событий кнопки.

Решение:

Сделайте DrawerViewController переменной экземпляра и инициализируйте ее в контроллере основного представления.

Другие вопросы по тегам