Установите пользовательский подкласс UINavigationBar в UINavigationController программно

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

Это - вещь операционной системы, не вещь Python. Это - то же на всех языках.

то, Что я обычно делаю, читается из файла, сделайте модификации и выпишите его в новый файл, названный myfile.txt.tmp или чем-то как этот. Это лучше, чем чтение целого файла в память, потому что файл может быть слишком большим для этого. Как только временный файл завершается, я переименовываю его то же как исходный файл.

Это - хороший, безопасный способ сделать это потому что, если катастрофические отказы записи файла или аварийные прекращения работы по какой-либо причине, у Вас все еще есть свой нетронутый исходный файл.

92
задан Dan Rosenstark 26 May 2012 в 13:09
поделиться

2 ответа

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

Что вы пытаетесь сделать, чтобы создать подкласс?

Кроме того, я не думаю, что IB фактически заменяет панель навигации. Я почти уверен, что он просто не отображает панель по умолчанию и имеет вашу настраиваемую панель навигации в качестве подпредставления. Если вы вызовете UINavigationController.navigationBar, получите ли вы экземпляр своей панели?

0
ответ дан 24 November 2019 в 06:26
поделиться

Насколько я могу судить, иногда действительно необходимо подкласс UINavigationBar, чтобы сделать нестандартный рестайлинг. Иногда можно избежать этого, используя категории, но не всегда.

В настоящее время, насколько я знаю, единственный способ установить пользовательский UINavigationBar внутри UIViewController - это через IB (то есть через архив) - вероятно, так быть не должно, но пока нам придется с этим жить.

Часто это нормально, но иногда использование IB не совсем целесообразно.

Итак, я видел три варианта:

  1. Подкласс UINavigationBar и подключить все это в IB, а затем возиться с загрузкой nib каждый раз, когда мне нужен UINavigationController,
  2. Использовать замену метода в категории для изменения поведения UINavigationBar, а не подкласс, или
  3. Подкласс UINavigationBar и немного повозиться с архивированием/разархивированием UINavigationController.

Вариант 1 был невыполним (или, по крайней мере, слишком раздражающим) для меня в данном случае, так как мне нужно было создать UINavigationController программно, 2 - немного опасен и, на мой взгляд, является скорее последним вариантом, поэтому я выбрал вариант 3.

Мой подход заключался в создании 'шаблонного' архива UINavigationController и разархивировании его, возвращая его в initWithRootViewController.

Вот как:

В IB я создал UINavigationController с соответствующим классом, установленным для UINavigationBar.

Затем я взял существующий контроллер и сохранил его архивную копию с помощью +[NSKeyedArchiver archiveRootObject:toFile:]. Я просто сделал это внутри делегата приложения в симуляторе.

Затем я использовал утилиту 'xxd' с флагом -i для генерации c-кода из сохраненного файла, чтобы встроить архивированную версию в мой подкласс (xxd -i path/to/file).

В initWithRootViewController я распаковываю этот шаблон и устанавливаю self в результат распаковки:

// This is the data from [NSKeyedArchiver archivedDataWithRootObject:controller], where
// controller is a CTNavigationController with navigation bar class set to CTNavigationBar,
// from IB.  This c code was created using 'xxd -i'
static unsigned char archived_controller[] = {
    0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd4, 0x01, 0x02, 0x03,
    ...
};
static unsigned int archived_controller_len = 682;

...

- (id)initWithRootViewController:(UIViewController *)rootViewController {
     // Replace with unarchived view controller, necessary for the custom navigation bar
     [self release];
     self = (CTNavigationController*)[NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithBytes:archived_controller length:archived_controller_len]];
     [self setViewControllers:[NSArray arrayWithObject:rootViewController]];
     return [self retain];
}

Затем я могу просто взять новый экземпляр моего подкласса UIViewController, в котором установлена пользовательская панель навигации:

UIViewController *modalViewController = [[[CTNavigationController alloc] initWithRootViewController:myTableViewController] autorelease];
[self.navigationController presentModalViewController:modalViewController animated:YES];

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

Я хотел бы видеть эквивалент +layerClass в UINavigationController - +navigationBarClass - но пока это работает.

26
ответ дан 24 November 2019 в 06:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: