尝试将数据从UIView传递到UIViewController时,我犯了什么错误?

时间:2019-12-16 16:50:22

标签: ios swift

我正在尝试为孩子们制作一个教育应用程序;到目前为止,屏幕上有一个“提示按钮”和一个UILabel,显示了孩子要求提示的次数。

按下提示按钮将显示一个弹出窗口(UIView),孩子可以通过按下另一个按钮来确认自己是否想要提示。现在,我希望将原来的UILabel增加一个,并在按下弹出式UIView上的第二个按钮后将此新增加的数字保存到userDefaults。

虽然我的代码设法将递增的数字保存为userDefaults,但UILabel直到应用程序被终止并重新启动后才反映此更改。

我将不胜感激。我不知道我在想什么。 (如果这个问题不适合该网站,请告诉我,我将其删除。)

我的代码:

class ViewController: UIViewController {

    let hintButton: UIButton = {
        let button = UIButton()
        button.setTitle("Hint me!", for: .normal)
        button.backgroundColor = .systemBlue
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        button.layer.cornerRadius = 12
        return button
    }()

    @objc func buttonPressed() {
        let pop = Popup()
        self.view.addSubview(pop)
    }

    var numberOfHintsRequested: Int {
           get {
               return UserDefaults.standard.integer(forKey: "hintsRequestedSaved")
           }
           set {
               UserDefaults.standard.set(newValue, forKey: "hintsRequestedSaved")
           }
       }

    lazy var hintsAskedLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont(name: "American Typewriter", size: 50)
        label.text = String(numberOfHintsRequested)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textAlignment = .center
        return label
    }()


    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        view.addSubview(hintButton)
        view.addSubview(hintsAskedLabel)

        NSLayoutConstraint.activate([
        hintButton.heightAnchor.constraint(equalToConstant: 80),
        hintButton.widthAnchor.constraint(equalToConstant: 150),
        hintButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        hintButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),

        hintsAskedLabel.heightAnchor.constraint(equalToConstant: 80),
        hintsAskedLabel.widthAnchor.constraint(equalToConstant: 80),
        hintsAskedLabel.bottomAnchor.constraint(equalTo: hintButton.topAnchor, constant: -180),
        hintsAskedLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor)

    ])

        }
    }

这是我的UIView:

class Popup: UIView {

    fileprivate let showHintButton: UIButton = {
        let button = UIButton()
        button.setTitle("Hint me NOW!!", for: .normal)
        button.backgroundColor = .systemBlue
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(showHintButtonPressed), for: .touchUpInside)
        button.layer.cornerRadius = 12
        return button
    }()

    @objc func showHintButtonPressed() {
        print("ZABOOKA")
        ViewController().numberOfHintsRequested += 1
        let text = UserDefaults.standard.object(forKey: "hintsRequestedSaved")
        if let unwrappedText = text {
            ViewController().hintsAskedLabel.text = unwrappedText as? String
        } else {
         print("NEHEHEHE")
        }
        print(ViewController().numberOfHintsRequested)
        self.containerDisappear()
    }

    fileprivate let container: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .white
        v.layer.cornerRadius = 24
        return v
    }()

    @objc fileprivate func containerDisappear() {
            self.alpha = 0
    }

    @objc fileprivate func containerAppear() {
        self.alpha = 1
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(containerDisappear)))
        self.backgroundColor = UIColor.gray
        self.backgroundColor?.withAlphaComponent(0.8)
        self.frame = UIScreen.main.bounds
        self.addSubview(container)

        container.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        container.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        container.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.7).isActive = true
        container.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.45).isActive = true

        container.addSubview(showHintButton)
        showHintButton.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true
        showHintButton.trailingAnchor.constraint(equalTo: container.trailingAnchor).isActive = true
        showHintButton.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
        showHintButton.heightAnchor.constraint(equalTo: container.heightAnchor, multiplier: 0.15).isActive = true

        containerAppear()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("BAD")
    }
}

2 个答案:

答案 0 :(得分:3)

您犯了一个非常常见的错误。

ViewController()的任何调用都会创建视图控制器的全新实例,在showHintButtonPressed中,您将创建三个不同的实例。

快捷解决方案是回调闭包。

PopUp中添加属性

var callback : (() -> Void)?

并替换

@objc func showHintButtonPressed() {
    print("ZABOOKA")
    ViewController().numberOfHintsRequested += 1
    let text = UserDefaults.standard.object(forKey: "hintsRequestedSaved")
    if let unwrappedText = text {
        ViewController().hintsAskedLabel.text = unwrappedText as? String
    } else {
     print("NEHEHEHE")
    }
    print(ViewController().numberOfHintsRequested)
    self.containerDisappear()
}

@objc func showHintButtonPressed() {
     callback?()
     self.containerDisappear()
}

另一个错误是,您将Int中的UserDefaults保存到ViewController并将其检索为String总是失败。


ViewController中替换

@objc func buttonPressed() {
    let pop = Popup()
    self.view.addSubview(pop)
}

使用

@objc func buttonPressed() {
    let pop = Popup()
    pop.callback = { [weak self] in
        var numberOfHints = self?.numberOfHintsRequested
        numberOfHints += 1
        self?.hintsAskedLabel.text = String(numberOfHints)
        self?.numberOfHintsRequested = numberOfHints
    }
    self.view.addSubview(pop)
}

答案 1 :(得分:0)

问题是您每次都创建一个新的ObservableCollection<KeyFreq>对象。最好使用委托将此更改传达给您现有的ViewController参考。

您可以在此处了解有关委托模式和协议的更多信息:

https://docs.swift.org/swift-book/LanguageGuide/Protocols.html

https://www.swiftbysundell.com/articles/delegation-in-swift/

示例

ViewController