Настройте вид оповещения с помощью нескольких кнопок - PullRequest
0 голосов
/ 20 декабря 2018

Я разрабатываю настраиваемый общий вид предупреждений, который показан ниже:

Просмотр предупреждений Снимок экрана

Screen Shot

Однако 2кнопки в этом представлении всегда выполняют одно и то же действие.

Он всегда выполняет вторую строку кода ниже для обеих кнопок.

optionAlertVC.btn_ok.actionHandle(controlEvents: .touchUpInside, ForAction: ok)
optionAlertVC.btn_cancel.actionHandle(controlEvents: .touchUpInside, ForAction: cancel)

Покажите код, помогающий мне решить эту проблему.

ViewController:

func logout() {
    AlertManager.shared.showAlertWithTwoOptions(viewController: self, message: "Confirm to logout?", okTitle: "Log out", dismissTitle: "Cancel", ok: {
        self.gotoLogin()
    }, cancel: {
        //nothing to do
    }, title: "Logout")
}

AlertManager:

typealias ok = () -> Void
typealias cancel = () -> Void
func showAlertWithTwoOptions(viewController: UIViewController, message: String, okTitle: String, dismissTitle:String, ok: @escaping ok , cancel: @escaping cancel, title:String? = nil) {
    guard let optionAlertVC = Bundle.main.loadNibNamed("AlertView", owner: nil, options: nil)?[1] as? OptionAlertVC else {
        print("error in loading error alert")
        return
    }
    optionAlertVC.lbl_title.text = title ?? "Warning"
    optionAlertVC.lbl_message.text = message
    optionAlertVC.iv_icon.image = UIImage(named: "icon_warning")
    optionAlertVC.btn_ok.backgroundColor = UIColor.MyTheme.greenSuccess
    optionAlertVC.btn_ok.setTitle(okTitle, for: .normal)
    optionAlertVC.btn_ok.titleLabel!.adjustsFontSizeToFitWidth = true
    optionAlertVC.btn_cancel.backgroundColor = UIColor.MyTheme.redWarning
    optionAlertVC.btn_cancel.setTitle(dismissTitle, for: .normal)
    optionAlertVC.btn_cancel.titleLabel!.adjustsFontSizeToFitWidth = true
    optionAlertVC.btn_cancel.titleLabel?.numberOfLines = 1

    optionAlertVC.btn_ok.actionHandle(controlEvents: .touchUpInside, ForAction: ok)
    optionAlertVC.btn_cancel.actionHandle(controlEvents: .touchUpInside, ForAction: cancel)

    viewController.present(optionAlertVC, animated: true, completion: nil)
}

UIButtonExtension:

extension UIButton {
    fileprivate func actionHandleBlock(action:(() -> Void)? = nil) {
        struct __ {
            static var action :(() -> Void)?
        }
        if action != nil {
            __.action = action
        } else {
            __.action?()
        }
    }

    @objc private func triggerActionHandleBlock() {
        self.actionHandleBlock()
    }

    func actionHandle(controlEvents control :UIControl.Event, ForAction action:@escaping () -> Void) {
        self.actionHandleBlock(action: action)
        self.addTarget(self, action: #selector(UIButton.triggerActionHandleBlock), for: control)
    }
}

1 Ответ

0 голосов
/ 20 декабря 2018

Во-первых, вы не должны обрабатывать button касания таким образом.Во-вторых, вы назвали struct плохо.Если мне нужно что-то сказать об этом struct, то как мне его назвать, чтобы вы знали, что я говорю об этом struct?

В связи с реальной проблемой, иногда становится сложно, когда вы обрабатываете что-то с помощью static.Поскольку вы объявили static var action (т. Е. static var action :(() -> Void)?) на struct ___, независимо от того, сколько у вас кнопок, он всегда будет вызывать последний обратный вызов кнопки (т. Е. closure), потому что это неarray, который может сохранять действия обратного вызова для всех кнопок, это всего лишь одна переменная, поэтому он будет перезаписывать предыдущий обратный вызов button самой последней.Я считаю, что вы должны удалить эту реализацию расширения UIButton, так как она будет вызывать нежелательные проблемы.

На самом деле вам не нужно ничего делать для обработки прикосновения UIButton.Просто объявите отдельный метод для каждой кнопки и сообщите кнопке об этом методе при добавлении цели, как показано ниже:

class OptionAlertVC: UIViewController {

    var btn_ok: UIButton!
    var btn_cancel: UIButton!

    public var okCallback: (() -> Void)?
    public var cancelCallback: (() -> Void)?

    override func viewDidLoad() {
        super.viewDidLoad()

        btn_ok.addTarget(self, action: #selector(okAction), for: .touchUpInside)
        btn_cancel.addTarget(self, action: #selector(cancelAction), for: .touchUpInside)
    }

    @objc func okAction() {
        okCallback?()
    }

    @objc func cancelAction() {
        cancelCallback?()
    }
}

Теперь, в showAlertWithTwoOptions, вы можете удалить следующие строки,

optionAlertVC.btn_ok.actionHandle(controlEvents: .touchUpInside, ForAction: ok)
optionAlertVC.btn_cancel.actionHandle(controlEvents: .touchUpInside, ForAction: cancel)

Вместо этого установите обратные вызовы следующим образом:

optionAlertVC.okCallback = ok
optionAlertVC.cancelCallback = cancel
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...