我有一個視圖控制器,它包含一個按鈕,當按下這個按鈕時,會呈現一個相機視圖控制器,允許用戶掃描一個條形碼,并將條形碼的值回傳到啟動它的第一個視圖控制器。
相機視圖控制器的呈現:
let ScannerView = scanBarcode()
let navigationController = UINavigationController(rootViewController: ScannerView)
navigationController.modalPresentationStyle = .formSheet
self.present(navigationController, animated: true, completion: nil)
掃描條形碼時執行的函式:
func processScan() {
print("Process Scanned")
NotificationCenter.default.post(name: Notification.Name("scannedInfo"/span>), object: nil。
userInfo:["barcodeValue": "123","value2": "Yes"])
解除(animated: true, completion: {
viewController1().observeScanned()
}
從ViewController1解雇時呼叫的函式
func observeScanned() {
NotificationCenter.default.addObserver(self,
選擇器。#selector(
self.ScanInfo(notification:))。
名稱。Notification.Name("ScanInfo"/span>)。
物件。nil)
}
@objc func ScanInfo(notification: Notification) {
print("ScanInfo"/span>)
barcode = notification.userInfo?["barcodeValue"] as? String>
value2 = notification.userInfo?["value2"] as?
print(barcode)
print(value2)
}
問題是通知觀察者的功能似乎沒有被觸發,barcodeValue和value2的值沒有被傳送到ViewController1。print(barcode)和print(value2)從未被列印。雖然我知道如果我以.fullscreen的方式呈現模態,我可以很容易地依賴ViewDidAppear,但我更愿意以表單或類似的方式呈現,因為螢屏并沒有被完全使用。
uj5u.com熱心網友回復:
你在這里有幾個問題。
首先,這個代碼:
viewController1().observeScanned()
創建一個新的viewController1實體,并呼叫其observeScanned函式 - 這個視圖控制器實體并不在螢屏上,一旦執行這一行就會被扔掉。
即使你在正確的實體上呼叫了observedScanned()函式,也已經太晚了。
這是你的第二個問題。 你提前兩行發布了通知。 當通知被發布時,它將被傳遞給已經為該通知注冊的觀察者。在通知發布后的觀察者將不會得到該通知,它只會得到后續的通知。
看起來你正在混合委托模式和通知。你只需要一個。
如果你只想使用通知,那么你可以在viewDidLoad中呼叫observeScanned,然后在你的scanBarcode視圖控制器中發布通知。scanBarcode沒有必要明確地呼叫viewController1中的任何方法 - Notifications的意義在于提供發送者和觀察者的解耦。
如果你只是想使用委托,那么你可以宣告一個協議
protocol ScannerDelegate {
func didScan(barcodeValue: String, value2: String) -> Void。
}
然后ViewController1可以符合這個協議,并將自己設定為ScanBarcode實體的委托人:
class ViewController1。UIViewController, ScannerDelegate{
// ...
let scannerView = scanBarcode()
scannerView.delegate =self
let navigationController = UINavigationController(rootViewController: ScannerView)
navigationController.modalPresentationStyle = .formSheet
self.present(navigationController, animated: true, completion: nil)
//...
func didScan(barcodeValue: String, value2: String) -> Void {
print("ScanInfo"/span>)
print(barcodeValue)
列印(value2)
}
}
最后,你的ScanBarcode需要提供一個delegate屬性并呼叫委托方法
class ScanBarcode。UIViewController {
var delegate: ScannerDelegate?
func processScan() {
print("Process Scanned")
self.delegate?.didScan(barcodeValue:"123"/span>, value2:"456"/span>)
解除(animated: true, completion: {
}
}
最后一件事。 你應該養成遵守Swift命名規則的習慣。 這并不影響你的代碼的作業方式,但它使你的代碼對其他人來說更易讀。
- 型別(類、結構、協議、列舉)使用UpperCamelCase,所以
ViewController1不是viewController1。
- 變數& 常量使用LowerCamelCase,所以
scannerView不是ScannerView。
我在這個答案中對你的代碼版本做了這些修改,所以你可以看到我所指的是什么。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/321926.html
標籤:
