Я хотел бы создать заголовок, который вообще не двигался бы в моем приложении, содержащем несколько ViewController. Мой заголовок - это просто представление, содержащее логотип (UIImageView), UIButton и UILabel. Я слышал, что могу сделать это с помощью UINavigationController или добавив подпредставление в UIWindow, но у меня это не работает (возможно, я делаю это неправильно). Моя основная проблема заключается в том, чтобы он оставался фиксированным в верхней части экрана (например, hud?) Во время анимации перехода, и мне также нужно было бы иметь возможность изменять содержимое UILabel во время процесса приложения.

Я работаю над Xcode 13 с раскадровкой для iOS 15 на iPad. Надеюсь, я достаточно ясно выразился.

ИЗМЕНИТЬ Похоже, что вставка представления в UIWindow будет для меня лучшим решением, хотя я не уверен, как это сделать правильно. Все примеры, которые я нахожу, не работают и устарели / устарели.

0
HydroMésange 11 Окт 2021 в 12:42

2 ответа

Лучший ответ

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

У меня есть одноэлементный класс для моего заголовка ViewController, который содержит элементы, которые мне нужны внутри него.

let HEADER = STORYBOARD.instantiateViewController(withIdentifier: "HeaderLayer") as? HeaderViewController

class HeaderViewController: UIViewController {

    @IBOutlet weak var ThemeLabel: UILabel!
    @IBOutlet weak var DifficultyImage: UIImageView!
    @IBOutlet weak var ExitButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        // ...
    }

    // Methods
}

А вот как я помещаю свой заголовок в UIWindow, чтобы он отображался в верхней части экрана, где он остается неизменным даже во время анимации перехода. Я меняю фрейм, потому что если он будет в полноэкранном режиме, это отключит взаимодействие для представлений внизу.

let STORYBOARD = UIStoryboard(name: "Main", bundle: nil)

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    
        HEADER!.view.frame = CGRect(x: 0, y: 0, width: 1366, height: 142)
        window?.addSubview(HEADER!.view)
        window?.makeKeyAndVisible()
    
        // ...
    }
    // ...
}

Затем необходимо выводить заголовок на передний план каждый раз, когда появляется один из моих ViewController.

class ViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    
        let window = UIApplication.shared.keyWindow
        window?.bringSubviewToFront(HEADER!.view)
    
        // ...
    }
}

Я не использую ни UINavigationController, ни UITabBarController, но это возможно с помощью этого метода.

Единственная проблема, с которой я столкнулся, заключается в том, что UIApplication.shared.keywindow устарел. Но, похоже, это не вызывает никаких проблем, и я еще не нашел решения.

0
HydroMésange 12 Окт 2021 в 10:52

Вы можете создать собственный UITabBarController , а затем добавить его в SceneDelegate как -

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
        
        let vc = CustomTab()
        self.window?.rootViewController = vc
        self.window?.makeKeyAndVisible()
        .......

В настраиваемом TabBar добавьте все свои контроллеры навигации как -

viewControllers = [nav1, nav2, nav3, nav4]

И в каждом классе контроллера представления вы можете скрыть, изменить или изменить свойства панели вкладок.

0
Imran0001 11 Окт 2021 в 12:25