Не могу понять, как использовать закрытие в Swift

Я пытаюсь использовать ActionSheetStringPicker в своем приложении iOS Swift. Я не могу понять, как использовать готовый блок или действие успеха. Вот мой код:

func pickerDone()
{
    println("Here I am!")
}

override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
{
    var selected = 0
    let done: ActionStringDoneBlock = {(picker: ActionSheetStringPicker!, selectedIndex: NSInteger!, selectedValue : AnyObject!) in
        println(selectedIndex)
    }

    var touch = touches.anyObject() as UITouch

    if touch.view is UILabel
    {
        var picker = ActionSheetStringPicker(title: "Select an attachment", rows: attachmentsList, initialSelection: 0, doneBlock: done, cancelBlock: nil, origin: touch.view)
        picker.showActionSheetPicker()
    }
}

Элемент, реагирующий на прикосновение, представляет собой UILabel с именем attachmentLabel, текст которого я хотел бы изменить в зависимости от выбора, сделанного в ActionSheetStringPicker. Однако, когда я попадаю внутрь готового блока, я получаю ошибку EXC_BAD_ACCESS всякий раз, когда пытаюсь получить доступ к чему-либо, кроме трех переданных параметров. И если я пытаюсь использовать функцию pickerDone в качестве успешного действия, она вызывается только в том случае, если Я определяю функцию так, чтобы она не принимала никаких параметров.

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

Я пытался выяснить, как захватить переменные для использования в моем закрытии, но я получаю ту же ошибку EXC_BAD_ACCESS. Я попытался захватить местного, но это не сработало:

var selected = 0
let done: ActionStringDoneBlock = {(picker: ActionSheetStringPicker!, selectedIndex: NSInteger!, selectedValue : AnyObject!) in
    selected = selectedIndex
}

Итак, я попытался захватить себя, но это тоже не работает:

let done: ActionStringDoneBlock = {[weak self](picker: ActionSheetStringPicker!, selectedIndex: NSInteger!, selectedValue : AnyObject!) in
    self?.attachmentLabel.text = self?.attachmentsList[selectedIndex]
    return
}

person aranha    schedule 17.12.2014    source источник


Ответы (1)


Я владелец ActionSheetPicker. Не пробовал работать с тачами Начал переопределять, но должно быть так же.

Я пытаюсь обернуть ваш код из touchesBegan в @IBAction, и он работает (выводит индекс после нажатия кнопки «Готово»):

@IBAction func doneBlockInvokeByDoneClicked(sender: UIButton) {
        var selected = 0
        let done: ActionStringDoneBlock = {(picker: ActionSheetStringPicker!, selectedIndex: NSInteger!, selectedValue : AnyObject!) in
            println(selectedIndex)
        }

        var picker = ActionSheetStringPicker(title: "Select an attachment", rows: ["One", "Two", "A lot"], initialSelection: 0, doneBlock: done, cancelBlock: nil, origin: sender.superview!.superview)

        picker.showActionSheetPicker()

    }

А вот пример запуска вашей функции из готового блока:

func pickerDone()
{
    println("Here I am!")
}

@IBAction func functionInvokeByDoneCicked(sender: UIButton) {
    var picker = ActionSheetStringPicker(title: "title", rows: ["1","2"], initialSelection: 0, target: self, successAction: "pickerDone", cancelAction: nil, origin: sender.superview!.superview)

    picker.showActionSheetPicker()
}

Вероятно, у вас проблема с параметром origin. Убедитесь, что touch.view является основным видом.

person skywinder    schedule 23.01.2015
comment
Я уже могу печатать из ActionStringDoneBlock или из готового блока, как вы сделали здесь. Проблема в том, что я не могу ничего делать, кроме как печатать. Я не могу получить доступ к каким-либо переменным внутри этих функций, кроме переданных, поэтому я не могу понять, как вернуть какую-либо информацию в свой пользовательский интерфейс. Например, я могу нормально распечатать выбранный индекс, но мне нужно вернуть значение выбранного индекса обратно в мой UILabel. - person aranha; 27.01.2015
comment
@aranha так же, как вы делаете это из других блоков или методов обратного вызова. 1) создайте выход для вашего текстового поля myTextField 2) замените println например на self.myTextField.text = self.arrayWithStrings[selectedIndex]. Посмотрите пример проекта на github.com/skywinder/ActionSheetPicker-3.0 Вы можете найти примеры этого действия там. - person skywinder; 28.01.2015
comment
У меня есть метка и список строк: @IBOutlet weak var attachmentLabel: UILabel! var attachmentsList = [String]() Список заполняется в другом месте. Если я выполню такое действие: let done: ActionStringDoneBlock = {[weak self](picker: ActionSheetStringPicker!, selectedIndex: NSInteger!, selectedValue : AnyObject!) in var index: Int = selectedIndex self?.attachmentLabel.text = self?.attachmentsList[index] } произойдет сбой с ошибкой EXC_BAD_ACCESS. Извините, я попытался отформатировать это красиво, но я не могу понять, как сделать так, чтобы разрывы строк отображались. - person aranha; 29.01.2015
comment
@aranha, лучше открыть задачу в репозитории на GitHub и продолжить обсуждение там с приятно- отформатированные комментарии. - person skywinder; 29.01.2015
comment
У меня такая же проблема с ошибкой EXC_BAD_ACCESS при попытке доступа к переменной в готовом блоке. У вас уже есть решение этой проблемы? - person ManzMoody; 12.02.2015
comment
@ManzMoody, пожалуйста, откройте задачу на странице github и подробно опишите свой случай - person skywinder; 12.02.2015