Подтвердить что ты не робот

UINavigationItem, центрирующий название

У меня есть панель навигации с левой и правой клавишами на каждой стороне. У меня есть customTitlelabel, который я задал как titleView UINavigationItem.

[self.navigationItem setTitleView: customTitleLabel];

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

Поэтому заголовок автоматически центрируется на основе доступного пространства между кнопками.

Как я могу установить заголовок на фиксированную позицию?

4b9b3361

Ответ 1

Вы не можете делать то, что хотите напрямую - позиция вашего заголовка не соответствует вашему управлению (когда управляется UINavigationBar).

Однако для получения желаемого эффекта есть как минимум две стратегии:

1) Добавьте название заголовка не как "правильное" название заголовка панели навигации, а как подпункт UINavigationBar. (Обратите внимание: это не "официально" санкционировано, но я видел, как это делается и работает. Очевидно, вам нужно следить за тем, чтобы ваш ярлык названия переписывал биты кнопок и обрабатывал различные бары на разных уровнях для разных ориентаций и т.д. - немного странно.)

2) Создайте интеллектуальный подкласс UIView, который отобразит данный подъярус (который будет вашим UILabel) в позиции, рассчитанной так, чтобы эффективно отображать подвью, идеально расположенную на экране. Чтобы сделать это, ваш интеллектуальный подкласс UIView будет реагировать на события макета (или изменения свойств t22 и т.д.), Изменив положение (frame) подвью. Label.

Лично мне нравится идея подхода 2) лучшая.

Ответ 2

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

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

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

Вот пример кода, который создает пользовательский заголовок с ярлыком, который остается центрированным в UINavigationBar независимо от ориентации, ширины влево или вправо:

self.title = @"My Centered Nav Title";

// Init views with rects with height and y pos
CGFloat titleHeight = self.navigationController.navigationBar.frame.size.height;
UIView *titleView = [[UIView alloc] initWithFrame:CGRectZero];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];

// Set font for sizing width
titleLabel.font = [UIFont boldSystemFontOfSize:20.f];

// Set the width of the views according to the text size
CGFloat desiredWidth = [self.title sizeWithFont:titleLabel.font
                            constrainedToSize:CGSizeMake([[UIScreen mainScreen] applicationFrame].size.width, titleLabel.frame.size.height)
                                lineBreakMode:UILineBreakModeCharacterWrap].width;

CGRect frame;

frame = titleLabel.frame;
frame.size.height = titleHeight;
frame.size.width = desiredWidth;
titleLabel.frame = frame;

frame = titleView.frame;
frame.size.height = titleHeight;
frame.size.width = desiredWidth;
titleView.frame = frame;

// Ensure text is on one line, centered and truncates if the bounds are restricted
titleLabel.numberOfLines = 1;
titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
titleLabel.textAlignment = NSTextAlignmentCenter;

// Use autoresizing to restrict the bounds to the area that the titleview allows
titleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
titleView.autoresizesSubviews = YES;
titleLabel.autoresizingMask = titleView.autoresizingMask;

// Set the text
titleLabel.text = self.title;

// Add as the nav bar titleview
[titleView addSubview:titleLabel];
self.navigationItem.titleView = titleView;

Ответ 3

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.navigationBar.topItem?.title = ""
}

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    navigationItem.title = "Make peace soon"
}

Ответ 4

Правильный ответ - переопределить sizeThatFits: вашего пользовательского titleView и вернуть его размер содержимого. Навигационная панель центрирует пользовательский заголовок, пока не останется свободного места.

Например, если у вас есть контейнер UIView с UILabel внутри:

@interface CustomTitleView : UIView

@property UILabel* textLabel;

@end

@implementation CustomTitleView

- (CGSize)sizeThatFits:(CGSize)size {
    CGSize textSize = [self.textLabel sizeThatFits:size];
    CGSize contentSize = size;
    contentSize.width = MIN( size.width, textSize.width );

    return contentSize;
}

@end

Ответ 5

Я попытался ответить aopsfan, но это не сработало. Точка останова показала, что центр бара был "(480,0, 22,0)" (координата X отсутствует).

Поэтому я изменил его на следующее:

- (void)layoutSubviews 
{
    [super layoutSubviews];

    // Center Title View

    UINavigationItem* item = [self topItem]; // (Current navigation item)

    [item.titleView setCenter:CGPointMake(160.0, 22.0)]; 
    // (...Hard-coded; Assuming portrait iPhone/iPod touch)

}

... и он работает как шарм. Эффект слайда/затухания при нажатии на контроллеры просмотра не поврежден. (iOS 5.0)

Ответ 6

У меня была аналогичная проблема. введите описание изображения здесь Мое решение - скрыть исходную кнопку "Назад", добавить добавить свою собственную реализацию. Поскольку система зарезервирует место для левых элементов.

UIImage* cancelIcon = [UIImage imageNamed:@"ic_clear"];
UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc] initWithImage:cancelIcon style:UIBarButtonItemStylePlain target:self action:@selector(back:)];

и селектор прост

- (void)back:(UIButton *) sender
{
    [self.navigationController popViewControllerAnimated:YES];
}

теперь он выглядит так: введите описание изображения здесь

oh... и не забудьте использовать автозапуск в своем пользовательском заголовке, если в нем есть динамическое содержимое длины, такое как метка. Я добавляю дополнительный макет в пользовательское представление, чтобы дать ему как "wrap_content" в Android, установив его в центре на родительский, а ведущее и конечное пространство " > =" 0

введите описание изображения здесь

Ответ 7

У меня была аналогичная ситуация, когда a titleView должен быть сосредоточен в UINavigationBar. Мне нравится окклюзионный подход подкласса UIView и переопределение setFrame:. Затем я могу центрировать рамку внутри размеров UINavigationBar.

В подклассе UIView:

-(void)setFrame:(CGRect)frame{
  super.frame = CGRectMake(320 / 2 - 50, 44 / 2 - 15, 100, 30);
}

Подкласс UIView можно затем назначить обычно titleView для каждого элемента навигации. Разработчику не нужно программно добавлять и удалять специальные подпрограммы из UINavigationBar.