2016-07-24 3 views
2

Я новичок в разработке iOS, поэтому простите меня, если мне не хватает чего-то очевидного. У меня есть контроллер представления, который содержит подвью, в котором я создал numpad, и пока я хочу дать numpad просмотр своего собственного подкласса UIView, потому что я хочу сделать с ним несколько разных вещей. Прямо сейчас numpad просто создает строку из нажатых клавиш, и я настроил делегат, чтобы передать эту строку в другом месте, где я хочу ее использовать (хотя я также попытался получить доступ к исходному вводу непосредственно в представлении контроллер с let a = subview(); label.text = a.rawInput).Swift 2.2 - Обновление UILabel бросает «неожиданно найдено нуль при распаковке необязательного значения»

Всякий раз, когда я пытаюсь установить текст UILabel в контроллере представления на необработанный вход subview, независимо от того, делегируется ли или нет, UILabel обнаружен как nil и выбрасывает ошибку в заголовке.

Вещи, которые я пробовал:

  • Установка текста внутри переопределения viewDidLoad, так и вне его
  • Установка переменной (testInput) внутри контроллера представления принять необработанный ввод в подвид и установив (я подтвердил, что переменная внутри контроллера представления правильно настроена, поэтому никаких проблем с делегацией)
  • Использование didSet в переменной testInput как для установки текста меток на testInput, так и для вызова вызова viewDidLoad и установки метки текст там (печать testInput внутри этого didSet выводит правильную строку, F WIW)
  • Удаление и перекомпоновки в IBOutlet для моего лейбла
  • Сильные и слабые хранения для IBOutlet переменной
  • Попытка сделать то же самое в другой подвид внутри контроллера представления, в случае, если по какой-то причине это было мнение собственная ошибка контроллера
  • Поиск везде решение, которое работает

я тупик. Вот мой соответствующий код Numpad:

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 
} 

Как примечание стороны, в случае, если вы заметили, что мой протокол не является типом класса, для некоторых причина добавляет: класс к нему и объявление моего делегата в качестве слабой переменной не позволяет делегации работать. Есть предложения?

ответ

2

Вы назначен делегатом так:

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), вы используете IBOutlet, который вы подключили в Interface Builder, а не программно создаете новый Numpad с Numpad().

+0

typo on 'weak var delegate; NumpadDelegate? '. ':' вместо ';' –

+1

Спасибо. Обновленный ответ. – Rob

+0

Благодарим вас за ответ. Если я раскомментирую эту строку, но не numpad = Numpad(), то numpad является нерешенным идентификатором. Если я изменю его на Numpad.delegate = self, он говорит, что «делегат-член экземпляра» не может использоваться для типа «Numpad» ». Если я изменю его на Numpad(). Delegate = self, ошибки нет, но делегация перестает работать. Какие-либо предложения? – Justin

Смежные вопросы

 Смежные вопросы