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



我正在尝试为孩子们制作一个教育应用程序;截至目前,屏幕上有一个"提示按钮"和一个UILabel,显示一个孩子请求提示的次数。

按下提示按钮会显示一个弹出窗口(UIView(,孩子可以通过按另一个按钮来确认他/她想要提示。现在,我希望将原始UILabel递增1,并在按下弹出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")
}
}

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

任何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()
}

另一个错误是,您正在保存IntViewControllerUserDefaults并检索它,因为String总是会失败。


ViewController替换

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

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

问题是您每次都会创建一个新的ViewController对象。最好使用委托将此更改传达到您现有的ViewController引用。

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

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

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

protocol PopupDelegate: class {
func popupViewDidTapActionButton(_ popup: Popup)
}
class Popup: UIView {
weak var delegate: PopupDelegate?
@objc func showHintButtonPressed() {
delegate?.popupViewDidTapActionButton(self)
}
}
class MyController: UIViewController {
func showpopUp() {
let pop = Popup()
pop.delegate = self
}
}
extension MyController: PopupDelegate {
func popupViewDidTapActionButton(_ popup: Popup) {
//UPDATE YOUR UI
}
}

最新更新