На полпути я создал приложение для MacOS (мое первое приложение, которое не входит в учебное пособие «Ваше первое приложение»), включающее множество пользовательских опций в главном окне, и ему надоел тот факт, что мой ViewControllerфайл превратился в громоздкий беспорядок, который не собирался обслуживать в долгосрочной перспективе.
Я решил разбить его, вводя несколько контроллеров представлений в более мелкие порции, чтобы сделать его более управляемым, используя представления контейнеров в UIBuilder для встраивания представлений,но все учебники, которые я нашел, были либо для устаревших версий Xcode / Swift, либо для управления несколькими представлениями в iOS, поэтому мне пришлось немного экстраполировать, и я, возможно, сделал это неправильно.
Теперь я 'я получаю сообщение об ошибке метода в одном ViewController, когда метод вызывается другим ViewController, даже если этот метод работает, находят при вызове его собственным контроллером представления.
Либо я пропускаю что-то очевидное, либо я установилвсе не так.
Глобальные переменные:
var inputPathUrl = URL?
var outputExtension: String = ""
@ IBOutletsи локальные свойства для класса InOutViewController
:
@IBOutlet weak var inputTextDisplay: NSTextField!
@IBOutlet weak var outputTextDisplay: NSTextField!
@IBOutlet weak var inputBrowseButton: NSButton!
@IBOutlet weak var outputBrowseButton: NSButton!
var outputDirectoryUrl: URL?
var inputFilePath: String = ""
@ IBOutlets для класса OptionsViewController
@IBOutlet weak var Button1: NSButton!
@IBOutlet weak var Button2: NSButton!
@IBOutlet weak var Button3: NSButton!
@IBOutlet weak var Button4: NSButton!
@IBOutlet weak var Button5: NSButton!
Методы для класса InOutViewController
:
@IBAction func InputBrowseClicked(\_ sender: Any) {
let inputPanel = NSOpenPanel()
inputPanel.canChooseFiles = true
inputPanel.canChooseDirectories = false
inputPanel.allowsMultipleSelection = false
inputPanel.allowedFileTypes = \["aax"\]
let userChoice = inputPanel.runModal()
switch userChoice{
case .OK :
if let inputFileChosen = inputPanel.url {
inputFileUrl = inputFileChosen // define global variable that will be called by other methods in other classes to check if an input file has been chosen
updateInputText() // call methods to display path strings in text fields
updateOutputText()
}
case .cancel :
print("user cancelled")
default :
break
}
}
@IBAction func outputBrowseClicked(_ sender: Any) {
let outputPanel = NSOpenPanel()
outputPanel.canChooseFiles = false
outputPanel.canChooseDirectories = true
outputPanel.allowsMultipleSelection = false
let userChoice = outputPanel.runModal()
switch userChoice{
case .OK :
if let outputUrl = outputPanel.url {
outputDirectoryUrl = outputUrl
updateOutputText()
}
case .cancel :
print("user cancelled")
default:
break
}
}
func updateInputText() {
// call getOutputOption method to see which radio button is selected
OptionsViewController().getOutputOption()
if inputFileUrl != nil {
inputFilePath = inputFileUrl!.path
inputTextDisplay.stringValue = inputFilePath
}
}
func updateOutputText() {
// derive output file path and name from input if no output location is chosen
if inputFileUrl != nil && outputDirectoryUrl == nil {
let outputDirectory = inputFileUrl!.deletingPathExtension()
let outputDirectoryPath = outputDirectory.path
let outputPath = outputDirectoryPath + "(outputExtension)"
outputTextDisplay.stringValue = outputPath
} else if inputFileUrl != nil && outputDirectoryUrl != nil {
// derive default file name from input but use selected output path if one is chosen
let outputDirectoryPath = outputDirectoryUrl!.path
let outputFile = inputFileUrl!.deletingPathExtension()
let outputFilename = outputFile.lastPathComponent
// derive file extension from getOutputOption method of OptionsViewController class
let outputPath = outputDirectoryPath + "/" + outputFilename + "(outputExtension)"
outputTextDisplay.stringValue = outputPath
}
}
Эта последняя строка (outputTextDisplay.stringValue = outputPath
) - это то, что я получаю фатальную ошибку, но ТОЛЬКО когда я вызываю этот метод из @IBAction
для переключателей формата вывода в OptionsViewController
, чтобы обновить отображение вывода, когдавыбрано другое расширение файла. Когда я вызываю метод из методов действий в InOutViewController
, он работает нормально.
Вот методы @IBAction
и getOutputOption
из класса OptionsViewController
:
@IBAction func radioButtonClicked(_ sender: Any) {
getOutputOption()
// update display with new file extension
InOutViewController().updateOutputText()
}
func getOutputOption() {
// make sure an input file has been chosen
if inputFileUrl != nil {
// check which radio button is selected and derive output file format based on selection
// not sure why I need to specify the button isn't nil, since one is ALWAYS selected, but I was getting a fatal error without doing so
if (Button1 != nil) && Button1.state == .on {
outputExtension = ".extA"
} else if (Button2 != nil) && Button2.state == .on {
outputExtension = ".extB"
} else if (Button3 != nil) && Button3.state == .on {
outputExtension = ".extC"
} else if (Button4 != nil) && Button4.state == .on {
outputExtension = ".extD"
} else {
outputExtension = ".extE"
}
}
}
Я уверен, что упускаю что-то очевидное, но, как я уже сказал, я впервые работаю с несколькими контроллерами представления, и я не уверен, что реализовал их должным образом, и я кодировал только несколько недель,так что я не могу определить, где я иду не так.