Добавление пользовательского представления над контроллером панели навигации/навигационным контроллером?

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

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

Я попытался установить рамку контроллера панели вкладок, но это вообще не двигало его.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{    
    // Override point for customization after application launch.
    // Add the tab bar controller current view as a subview of the window
    //self.tabBarController.view.frame = CGRectMake(0, 62, 320, 320);
    self.window.rootViewController = self.tabBarController;

    [self.window makeKeyAndVisible];

    // setting up the header view
    self.headerView = [[HeaderView alloc] initWithFrame:CGRectMake(0, 20, 320, 42)];
    [self.window addSubview:self.headerView];

    // setting up facebook stuff
    AgentSingleton *agentSingleton = [AgentSingleton sharedSingleton];
    agentSingleton.facebook = [[Facebook alloc] initWithAppId:APP_ID];

    return YES;
}

Любые идеи?

Ответ 1

На самом деле нет хорошего способа сделать это. Различные подпрограммы UINavigationController и UITabBarController являются частными, и попытки с ними с ними работать, вероятно, будут работать неправильно. И Apple не дает нам инструментов для создания контроллеров вида "контейнер", поэтому вы не можете легко встраивать UINavigationController/UITabBarController в другой контроллер представления или самостоятельно воссоздавать UINavigationController/UITabBarController.

Лучше всего, наверное, пойти дальше и попытаться создать свой собственный контроллер контейнера и обработать некоторые вещи, которые не работают правильно. В частности, встроенный контроллер представления parentViewController будет возвращать нуль, поэтому различные другие элементы на встроенном контроллере представления или его субконтроллерах будут разбиты (например, свойство interfaceOrientation будет неправильным, presentModalViewController:animated: может не работать правильно). Другие вещи также могут быть нарушены.

Или вы можете подождать, пока какая-то будущая версия iOS фактически не поддержит нас для создания контроллеров контейнеров (если вообще), а затем поддержит только эту версию и до.

Ответ 2

Добавить представление в окно tabBarController:

[self.tabBarController.view addSubview:yourView];

Ответ 3

Вы можете просто добавить addSubview в окно:

[self.view.window addSubview:myView];

Ответ 4

Вы можете сделать что-то вроде этого:

if let indeedTabBarController = self.tabBarController {

    let buttonHeight: CGFloat = 49 // height of tab bar
    let buttonWidth = UIScreen.main.bounds.width / 3 // in case if you have 3 tabs
    let frame = CGRect(x: 0, y: UIScreen.main.bounds.height - buttonHeight, width: buttonWidth, height: buttonHeight)
    let button = UIButton(frame: frame)
    button.addTarget(self, action: #selector(self.someAction), for: .touchUpInside)

    indeedTabBarController.view.addSubview(button)
}

Ответ 5

Вы имеете в виду выше, как в вертикальном положении над остальной частью содержимого?

Или выше, как при сидении поверх остальных содержимого?

Там presentModalViewController: анимированный: но я сомневаюсь, что вы хотите?

Ответ 6

Я не могу комментировать, поэтому напишу это здесь для всех, кто попадает на эту страницу. Ответ Борута, который был проголосован, был на самом деле более легким и правильным ответом.

Он просто не предоставил вам правильные указания. Вам нужно добавить пользовательское представление к окну для вашего приложения, которое объявлено в вашем AppDelegate (в Mono это будет AppDelegate.Window.Add(myView), а не в текущем окне просмотра, которое является нулевым (например, this.View.Window).

Это отлично работает в Xamarin/Mono, и я не понимаю, почему это не будет одинаковым для Obj-C в правильном коде.

Ответ 7

У меня была та же проблема, и в итоге я сделал что-то вроде этого:

self.newView.frame = self.tabBarController.tabBar.frame
self.tabBarController.view.addSubview(self.newView)

Добавление представления к tabBarController и использование рамки текущей вкладки в качестве позиции нового представления сделали свое дело.

Ответ 8

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let indeedTabBarController = self.tabBarController {
    let buttonHeight: CGFloat = view.safeAreaInsets.bottom + 44
    let buttonWidth = UIScreen.main.bounds.width
    let frame = CGRect(x: 0, y: UIScreen.main.bounds.height - buttonHeight, width: buttonWidth, height: 44)
    let vw = UIView(frame: frame)
    vw.backgroundColor = .red
    indeedTabBarController.view.addSubview(vw)
  }
}