Проблема с заголовком окна в моем текстовом редакторе на macOS, разработанном с использованием SwiftUI

Вопрос или проблема

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

Когда я впервые открываю приложение, заголовок окна правильно отображает “Без названия”, что мне нужно. Однако, если я закрою приложение, используя встроенную кнопку закрытия в верхнем левом углу (вместо выхода из приложения), и затем заново открою его, заголовок окна изменится на название приложения вместо того, чтобы вернуться к “Без названия”.

Кроме того, когда я открываю файл, заголовок окна изменяется на название приложения, а не на название открываемого файла.

Вот соответствующая часть моего кода:

    import SwiftUI

    struct ContentView: View {
        @State private var text: String = ""
        @State private var currentFileURL: URL?
        @State private var windowTitle: String = "Без названия"

        var body: some View {
            VStack {
                TextEditor(text: $text)
                    .padding()
            }
            .frame(minWidth: 600, minHeight: 400)
            .onAppear {
                updateWindowTitle()
            }
            .onReceive(NotificationCenter.default.publisher(for: .openFile)) { _ in
                openFile()
            }
            .onReceive(NotificationCenter.default.publisher(for: .saveFile)) { _ in
                saveFile()
            }
        }

        func openFile() {
            let panel = NSOpenPanel()
            panel.allowedFileTypes = ["txt"]
            panel.allowsMultipleSelection = false
            panel.canChooseDirectories = false

            if panel.runModal() == .OK, let url = panel.url {
                do {
                    let fileContents = try String(contentsOf: url, encoding: .utf8)
                    self.text = fileContents
                    self.currentFileURL = url
                    updateWindowTitle(with: url)
                } catch {
                    print("ошибка: \(error.localizedDescription)")
                }
            }
        }

        func saveFile() {
            if let url = currentFileURL {
                do {
                    try text.write(to: url, atomically: true, encoding: .utf8)
                    updateWindowTitle(with: url)
                } catch {
                    print("ошибка: \(error.localizedDescription)")
                }
            } else {
                let panel = NSSavePanel()
                panel.allowedFileTypes = ["txt"]
                panel.nameFieldStringValue = "new.txt"

                if panel.runModal() == .OK, let saveURL = panel.url {
                    do {
                        try text.write(to: saveURL, atomically: true, encoding: .utf8)
                        self.currentFileURL = saveURL
                        updateWindowTitle(with: saveURL)
                    } catch {
                        print("ошибка: \(error.localizedDescription)")
                    }
                }
            }
        }

        func updateWindowTitle(with fileURL: URL? = nil) {
            let window = NSApplication.shared.windows.first
            if let url = fileURL {
                window?.title = url.lastPathComponent
            } else {
                window?.title = "Без названия"
            }
        }
    }

Я был бы признателен за любые советы о том, как гарантировать, чтобы заголовок окна вел себя ожидаемым образом — показывал “Без названия”, когда файлы не открыты, и отображал имя файла, когда файл открыт.

Спасибо за вашу помощь!

Ответ или решение

Проблема с заголовком окна в приложении текстового редактора на macOS, разработанном на SwiftUI

Введение

Разработка текстового редактора на SwiftUI может оказаться увлекательной задачей. Однако, как и в любом проекте, иногда возникают трудности, связанные с функциональностью. В вашем случае проблема заключается в неправильном отображении заголовка окна при открытии и закрытии приложения, а также изменении имени файла после открытия.

Проблема

Вы описали две ключевые проблемы:

  1. При повторном запуске приложения заголовок окна меняется с "Untitled" на название приложения.
  2. При открытии файла заголовок окна должен менять свое значение на имя открытого файла, но вместо этого отображается название приложения.

Это может быть связано с тем, как вы обрабатываете состояние приложения и с тем, как обновляется заголовок окна в разных случаях.

Решение

Для решения вашей проблемы необходимо внести небольшие изменения в вашу реализацию, чтобы убедиться, что заголовок окна обновляется в зависимости от состояния приложения. Рассмотрим, как это можно сделать.

  1. Добавьте обработку события при закрытии окна.
    Вам нужно будет установить значение заголовка окна в "Untitled" при запуске приложения. Можно использовать метод applicationDidFinishLaunching, чтобы инициализировать заголовок.

  2. Измените метод updateWindowTitle.
    Данный метод должен более четко разделять ситуации при открытии файла и при отсутствии открытых файлов. Изменения должны выглядеть следующим образом:

func updateWindowTitle(with fileURL: URL? = nil) {
    guard let window = NSApplication.shared.windows.first else { return }

    if let url = fileURL {
        window.title = url.lastPathComponent
    } else {
        window.title = "Untitled"
    }
}
  1. Добавьте обработчик при перезапуске приложения.
    Убедитесь, что ваше приложение правильно переходит в состояние "Untitled" при старте. Например:
@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear {
                    NSApplication.shared.windows.first?.title = "Untitled"
                }
        }
    }
}
  1. Убедитесь, что заголовок окна обновляется после открытия файла.
    Проверьте, что updateWindowTitle(with: url) вызывается правильно в методах openFile и saveFile, чтобы заголовок был всегда актуальным.

Пример кода

После внесения изменений ваш код может выглядеть следующим образом:

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear {
                    NSApplication.shared.windows.first?.title = "Untitled"
                }
        }
    }
}

struct ContentView: View {
    @State private var text: String = ""
    @State private var currentFileURL: URL?

    var body: some View {
        VStack {
            TextEditor(text: $text)
                .padding()
        }
        .frame(minWidth: 600, minHeight: 400)
        .onAppear {
            updateWindowTitle()
        }
        .onReceive(NotificationCenter.default.publisher(for: .openFile)) { _ in
            openFile()
        }
        .onReceive(NotificationCenter.default.publisher(for: .saveFile)) { _ in
            saveFile()
        }
    }

    func openFile() {
        // Implement the file opening logic
    }

    func saveFile() {
        // Implement the file saving logic
    }

    func updateWindowTitle(with fileURL: URL? = nil) {
        let window = NSApplication.shared.windows.first
        if let url = fileURL {
            window?.title = url.lastPathComponent
        } else {
            window?.title = "Untitled"
        }
    }
}

Заключение

Следуя указанным выше рекомендациям, вы сможете корректно управлять заголовком окна в вашем текстовом редакторе на SwiftUI, обеспечивая правильное отображение имени файла или значения "Untitled". Убедитесь, что все элементы вашего проекта слаженно работают друг с другом для достижения оптимального результата.

Если у вас возникнут дополнительные вопросы или потребуется дальнейшая помощь, пожалуйста, не стесняйтесь обращаться.

Оцените материал
Добавить комментарий

Капча загружается...