Arhn - архитектура программирования

iOS 11 navigationItem.titleView Ширина не установлена

Наблюдение за поведением iOS11 с помощью navigationItem.titleView, где ширина titleView не равна полной ширине экрана.

У меня есть собственный вид, который я установил как titleView. До iOS11 представление заполняло область панели навигации. Но iOS 11 не меняет размер, чтобы заполнить ширину экрана.

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

Скриншоты прилагаются:

iOS10:

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

iOS11:

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

Кто-нибудь еще испытывает это?


Ответы:


1

Я понял. Мне пришлось переопределить геттер intrinsicContentSize для представления и текстового поля.

Я установил ширину CGFloat.greatestFiniteMagnitude, чтобы она всегда была такой же ширины, как экран.

Обновление:

Так как я потратил пару часов на эту проблему, надеюсь, что кто-то еще наверстает упущенное быстрее, если все вещи будут собраны вместе.

Я создал собственный подкласс TitleView, названный CustomTitleView, вот код:

import UIKit

class CustomTitleView: UIView {

  override var intrinsicContentSize: CGSize {
    return UIView.layoutFittingExpandedSize
  }
}

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

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

05.07.2017
  • В качестве объяснения: titleView теперь выложен с помощью Auto Layout. Так как он ищет intrinsicContentSize, это то, что сработало. 18.08.2017
  • Может ли заголовок отображаться под большим заголовком? Я назначил segmentedControl для просмотра заголовка, и он всегда отображался на большом заголовке. 25.08.2017
  • @Arco: Вы решили свою проблему? У меня такая же проблема с UISegmentedControl, помещенным внутри TitleView, и прикосновение не отвечает, повторно подключено и подклассифицировано UIView класс TitleView, который переопределяет свойство intrinsicContentSize как João Nunes, упомянутый в ответе ниже. 19.10.2017
  • @ el.severo Я не решаю свой вопрос, потому что думаю, что нет общедоступного API, чтобы мы могли назначить настраиваемое представление для места просмотра большого заголовка. Возможно, вы сможете увидеть структуру подвидов панели навигации и попытаться использовать среду выполнения Objective-C для решения вашей проблемы. 19.10.2017
  • @Arco: Спасибо, но мне удалось решить эту проблему, я только что отредактировал этот ответ и предоставил дополнительную информацию, надеюсь, что кому-то это пригодится. 19.10.2017
  • Проблема в том, что он также отталкивает от экрана левую и правую кнопки навигации. 20.12.2017
  • Как / где вы установили ширину? Сбросив рамку? 20.05.2019
  • Интересно. Оно работает! ???? Я пытался включить представление-разделитель в качестве последнего упорядоченного подпредставления, которое будет иметь ограничение по ширине для CGFloat.greatestFiniteMagnitude и распределение stackview как .fill, чтобы заполнить любое оставшееся пространство. В моем случае он перестал работать, когда на правой панели было больше одного элемента. 21.10.2020
  • Человек ты спас мне жизнь !!!. Это решение отлично работает и на iOS 14. 29.10.2020

  • 2

    Используя ответ @falkon, вот код:

    Добавьте этот код в представление, которое используется как titleView

    override var intrinsicContentSize: CGSize {
        return UILayoutFittingExpandedSize
    } 
    
    18.09.2017
  • Исправлено, но иногда заголовок перемещался под строку состояния после анимации оружия. 24.11.2017
  • Мне также пришлось добавить translatesAutoresizingMaskIntoConstraints = false к этому виду. 30.01.2018

  • 3

    Исправлено, создав подкласс UIView и назначив его для представления заголовка UINavigationController.

    Цель-C:

    #import "FLWCustomTitleView.h"
    
    @implementation FLWCustomTitleView
    
    - (CGSize )intrinsicContentSize {
      return UILayoutFittingExpandedSize;
    }
    
    @end
    

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

    29.09.2017
  • как вы добавили туда кастомный вид? 06.10.2018

  • 4

    установка intrinsicContentSize на UILayoutFittingExpandedSize также работает нормально

    06.09.2017

    5

    Мне пришлось уместить UIImageView как navigationItem.titleView. Соотношение сторон действительно подходило, но значение intrinsicContentSize стало большим. Масштабирование изображения привело к плохому качеству изображения. У меня сработала установка привязок макета:

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 80, 30)];
    [imageView setImage:image];
    [imageView.widthAnchor constraintEqualToConstant:80].active = YES;
    [imageView.heightAnchor constraintEqualToConstant:30].active = YES;
    [imageView setContentMode:UIViewContentModeScaleAspectFit];
    self.navigationItem.titleView = imageView;
    
    23.11.2017

    6

    Дополнение к существующим ответам:

    Если ваше настраиваемое представление заголовка - это представление, которое уже имеет внутренний размер содержимого по умолчанию (кроме .zero), например UILabel, _3 _ или UIButton, вы можете просто установить

    yourCustomTitleView.translatesAutoresizingMaskIntoConstraints = false
    

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


    Например, вы можете перетащить кнопку в область просмотра заголовка на панели навигации в Interface Builder, создать для нее выход titleButton в контроллере представления, а затем выполнить

    override func viewDidLoad() {
        super.viewDidLoad()
        titleButton.translatesAutoresizingMaskIntoConstraints = false
    }
    
    18.06.2018

    7

    Версия Swift 4.2 Ответ Йеди

    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 80, height: 30))
    imageView.image = image
    imageView.widthAnchor.constraint(equalToConstant: 80).isActive = true
    imageView.heightAnchor.constraint(equalToConstant: 30).isActive = true
    imageView.contentMode = .scaleAspectFit
    navigationItem.titleView = imageView
    

    Преобразовано с помощью Swiftify.

    18.01.2019

    8

    Самым важным является то, что вам нужно перезаписать customTitleView в качестве titleView:

    self.navigationItem.titleView = [self titleView];

    #pragma mark - getter
    
    - (UIView *)titleView {
        UIView *navTitleView = [HFCalenderTitleView new];
        navTitleView.frame = CGRectMake(0.0, 0.0, HorizontalFrom750(200.0), 44.0);
    
        [navTitleView addSubview:self.titleLabel];
        [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.center.equalTo(navTitleView);
        }];
    
        CGFloat btnWidth = 30.0;
        [navTitleView addSubview:self.previousButton];
        self.previousButton.imageEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, 15.0);
        [self.previousButton mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(navTitleView);
            make.top.bottom.equalTo(navTitleView);
            make.width.equalTo(@(btnWidth));
        }];
        [navTitleView addSubview:self.nextBtn];
        self.nextBtn.imageEdgeInsets = UIEdgeInsetsMake(0.0, 15.0, 0.0, 0.0);
        [self.nextBtn mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(navTitleView);
            make.top.bottom.equalTo(navTitleView);
            make.width.equalTo(@(btnWidth));
        }];
    
        return navTitleView;
    }
    #pragma mark - customTitleView
    
    #import "HFCalenderTitleView.h"
    @implementation HFCalenderTitleView
    - (CGSize)intrinsicContentSize{
        return CGSizeMake(HorizontalFrom750(200.0), 40); // the target size
    }
    

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

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

    25.09.2017

    9

    Когда у вас есть UIView as subview внутри CustomTitleView, решение intrinsicContentSize не работает, для меня в XCODE 9 только в iOS 11. так что я сделал, как показано ниже, отлично работает для меня, может ли это кому-то помочь.

    @interface CustomTitleView : UIView
    @property (weak, nonatomic) IBOutlet UIView *doubleTitleView;
    @end
    
    @implementation CustomTitleView
    - (void)awakeFromNib {
        [super awakeFromNib];
        int width = _doubleTitleView.frame.size.width;
        int height = _doubleTitleView.frame.size.height;
        if (width != 0 && height != 0) {
    
            NSLayoutConstraint *widthConstraint =  [_doubleTitleView.widthAnchor constraintEqualToConstant:width];
            NSLayoutConstraint *heightConstraint = [_doubleTitleView.heightAnchor constraintEqualToConstant:height];
    
            [_doubleTitleView addConstraint:heightConstraint];
            [_doubleTitleView addConstraint:widthConstraint];
            [heightConstraint setActive:TRUE];
            [widthConstraint setActive:TRUE];
        }
    }
    
    01.11.2017

    10

    Вы также можете использовать ограничения, если не хотите отменять intrinsicContentSize. Вот демонстрация SnapKit

    self.navigationItem.titleView = titleView
    if #available(iOS 11, *) {
        titleView.snp.makeConstraints({ (make) in
            make.width.equalTo(250) // fixed width
            make.height.equalTo(30) // less than 44(height of naviagtion bar)
        })
    }else {
        titleView.frame = ...
    }
    

    Но если на любой боковой (левой или правой) панели навигации расположено несколько элементов навигационной панели, следует использовать intrinsicContentSize;

    30.09.2017
  • Вы знаете, почему нужно быть меньше 44? Я стараюсь больше, но безуспешно. 20.10.2017

  • 11

    Этот класс сделает свое дело. Убедитесь, что вы установили класс своего пользовательского представления на этот:

    import UIKit
    
    class TitleView: UIView {
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            translatesAutoresizingMaskIntoConstraints = false
        }
    
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            translatesAutoresizingMaskIntoConstraints = false
        }
    
        override var intrinsicContentSize: CGSize {
            CGSize(width: UIView.layoutFittingExpandedSize.width, height: self.bounds.height)
        }
    
    }
    
    05.03.2020

    12

    У меня была такая же проблема, но с установкой UIImage в качестве navigationItem titleView

    Что я сделал, так это масштабировал изображение до необходимого размера, используя следующее:

    -(UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    
        UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
        [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return newImage;
    }
    

    И назовите это так:

    -(void)setHeaderImage{
        UIImage * image = [self imageWithImage:[UIImage imageNamed:@"headerImage"] scaledToSize:CGSizeMake(150, 27)];
        UIImageView *  imageView = [[UIImageView alloc]initWithImage:image];
        imageView.frame = CGRectMake(0, 0, 150, 27);
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        self.navigationItem.titleView = imageView;
    }
    
    24.09.2017
  • imageView.frame = CGRectMake (0, 100, 150, 27); можно ли изменить Y в его кадре? 09.07.2018
  • Вы можете поместить UIImageView внутрь UIView и изменить фрейм UIImageView 09.07.2018

  • 13

    return UILayoutFittingExpandedSize мне не помогло, т.к. вид добавлялся еще несколько раз по вертикали для заполнения макета.

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

     - (CGSize)intrinsicContentSize {
        //fills empty space. View will be resized to be smaller, but if it is too small - then it stays too small
        CGRect frame = self.frame;
        frame.size.width = MAX(SCREEN_WIDTH, SCREEN_HEIGHT);
        return frame.size;
    }
    
    16.11.2017

    14

    Попробуйте использовать стандартный UISearchBar / UISearchController

    Собственно, что вам нужно сделать - если вы можете использовать стандартный UISearchBar / UISearchController, - это отобразить панель поиска следующим образом, соблюдая безопасную область и, таким образом, идеально выглядя на iPhone X и в любой ориентации устройства:

    func presentSearchController() {
        let searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.text = "any text"
    
        if #available(iOS 11.0, *) {
            self.navigationItem.searchController = searchController
            searchController.isActive = true
        } else {
            present(searchController, animated: true, completion: nil)
        }
    }
    

    Ссылки

    https://developer.apple.com/videos/play/fall2017/201/ https://medium.com/@PavelGnatyuk/large-title-and-search-in-ios-11-514d5e020cee

    20.12.2017
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..


    © 2024 arhn.ru, Arhn - архитектура программирования