我是iOS开发的新手,所以如果我缺少明显的东西,请原谅我。我有一个视图控制器,其中包含一个子视图,在该子视图中我创建了一个数字键盘,目前,我想为数字键盘视图提供自己的UIView子类,因为我想用它做一些不同的事情。现在,数字键盘只是根据按下的键创建一个字符串,并且我已经建立了一个委托将该字符串传递给其他任何我想使用它的地方(尽管我也尝试过直接在视图中访问原始输入控制器,让a = subview(); label.text = a.rawInput)。
每当我尝试将视图控制器中的UILabel文本设置为子视图的原始输入时,无论是通过委派还是直接将其设置为nil,都会在标题中引发错误。
我尝试过的事情:
我很沮丧这是我相关的数字键盘代码:
import UIKit
protocol NumpadDelegate {
func updateInput(input: String)
}
class Numpad: UIView {
// MARK: UI outlets
@IBOutlet weak var decButton: UIButton!
// MARK: Properties
var rawInput: String = ""
var visibleInput: String = ""
var calcInput: String = ""
var operandReady = 1
var percentWatcher = 0
var delegate: NumpadDelegate? = BudgetViewController()
// MARK: Functions
func handleRawInput(str: String) {
rawInput += str
print("numpad input is \(rawInput)")
delegate?.updateInput(rawInput)
}
这是视图控制器代码:
import UIKit
class BudgetViewController: UIViewController, NumpadDelegate {
// MARK: Properties
//@IBOutlet weak var transactionValueField: UITextField!
@IBOutlet weak var remainingCashForIntervalLabel: UILabel!
@IBOutlet weak var intervalDenoterLabel: UILabel!
@IBOutlet weak var currencyDenoterLabel: UILabel!
@IBOutlet weak var mainDisplayView: TransactionType!
@IBOutlet weak var inactiveInputView: InactiveInput!
@IBOutlet weak var numpadView: Numpad!
@IBOutlet weak var rawInputLabel: UILabel!
var remainingCashForInterval = 40
let display = TransactionType()
var testInput = "" {
didSet {
viewDidLoad()
}
}
override func viewDidLoad() {
super.viewDidLoad()
// let numpad = Numpad()
// numpad.delegate = self
// print("\(numpad.delegate)")
self.rawInputLabel.text = testInput
}
func updateInput(input: String) {
print("view controller now has \(input)")
display.mainInput = input
testInput = input
}
附带说明一下,如果您发现我的协议不是类类型,出于某种原因,请在其中添加:class并将我的委托声明为弱变量,以防止委托起作用。有什么建议吗?
最佳答案
您像这样分配了代表:
var delegate: NumpadDelegate? = BudgetViewController()
那不引用呈现场景的视图控制器,而是引用一个新的空白视图控制器。这就是为什么当您使用
weak
时,为什么将其释放了(因为视图控制器的孤立实例对此没有强大的引用)。您应该再次将协议定义为
class
协议,并将delegate
定义为:weak var delegate: NumpadDelegate?
然后,在视图控制器的
viewDidLoad
中,取消注释设置该委托的行:numpadView.delegate = self
但是,请不要取消注释
numpad = Numpad()
的行;这是错误的,因为这会创建另一个Numpad
实例。但是,您确实想设置现有Numpad
的委托。这两个问题(即,获得要作为
Numpad
视图的委托的视图控制器的引用;获得对情节提要所呈现的Numpad
视图的引用)都对演示情节提要场景的过程产生了一些误解。 。该过程基本上如下:
view
以及该场景上的所有子视图都将为您实例化; IBOutlet
引用连接到您创建的出口。和viewDidLoad
。 这太简单了,但这是基本过程。
但关键是要为您创建所有在情节提要场景中引用的视图控制器和视图。您不想自己尝试创建其中的任何一个(并且
()
或BudgetViewController()
末尾的Numpad()
表示“创建x的新实例”,这不是我们想要在此处进行的操作)。因此,当我们需要获取对视图控制器的引用以便可以以编程方式为其中一个视图指定
delegate
时,可以在viewDidLoad
中进行此操作,此时self
引用故事板为我们实例化的视图控制器。我们不想实例化一个新实例。同样,当您要引用情节提要为我们实例化的Numpad
(以连接其delegate
)时,请使用在Interface Builder中连接的IBOutlet
,而不是通过Numpad
编程地实例化一个新的Numpad()
。