42

Widzenie zachowania na iOS11 za pomocą elementu navigationItem.titleView, gdzie szerokość tytułu titleView nie jest pełną szerokością ekranu.iOS 11 navigationItem.titleView Szerokość Nie ustawiona

Mam niestandardowy widok ustawiony jako titleView. Przed wersją iOS11 widok wypełniał pasek nawigacji. Ale iOS 11 nie zmienia rozmiaru, aby wypełnić szerokość ekranu.

Próbowałem ustawić ramkę widoku przed ustawieniem titleView, ale bez powodzenia. Próbowałem również wymusić na superView tytułu widoki ograniczeń układu, ale bez powodzenia.

ekranu załączone:

iOS10:

enter image description here

iOS11:

enter image description here

Ktoś jeszcze tego doświadczyć?

Odpowiedz

63

Wyjaśniałem to. Musiałem zastąpić geter intrinsicContentSize dla widoku i pola tekstowego.

Ustawię szerokość na CGFloat.greatestFiniteMagnitude, aby zawsze była tak szeroka jak ekran.

Aktualizacja:

Ponieważ spędziłem kilka godzin na ten temat, mam nadzieję, że jakiś inny złapie szybciej mając wszystko zejdzie się razem

I utworzeniu niestandardowego sub klasa TitleView, zwany CustomTitleView, oto kod:

import UIKit 

class CustomTitleView: UIView { 

    override var intrinsicContentSize: CGSize { 
    return UILayoutFittingExpandedSize 
    } 
} 

i najważniejsza część, która brakowało mi od samego początku było to:

enter image description here

+3

Jako Objaśnienie: titleView obecnie rozplanowane z Auto Layout. Ponieważ to wygląda na wewnętrznąContentSize, to właśnie zadziałało. – mangerlahn

+0

Czy może być wyświetlany tytuł widoku pod dużym widokiem tytułu? Przypisałem element sectionedControl do widoku tytułu, który zawsze pokazywał duży tytuł. – Arco

+0

Dziękujemy! To rozwiązało mój problem. – rilar

11

ustawienie intrinsicContentSize do UILayoutFittingExpandedSize działa dobrze również

+1

To jest poprawna odpowiedź –

31

Korzystanie odpowiedź @ Falkon za oto kod:

Dodaj ten kod do widoku, który jest używany jako titleView

override var intrinsicContentSize: CGSize { 
    return UILayoutFittingExpandedSize 
} 
+0

Perfect. To rozwiązało problem. Dzięki! – BEm

+0

Naprawiono, ale czasami widok tytułu porusza się pod paskiem stanu po animacji Wield. – Lumialxk

+0

Musiałem również dodać 'translatesAutoresizingMaskIntoConstraints = false' do tego widoku. – rafalkitta

0

Miałem ten sam problem, ale z ustawieniem UIImage jako navigationItemtitleView

co zrobiłem to ja przeskalowany obraz do potrzebnych rozmiarów za pomocą przycisków poniżej:

-(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; 
} 

i nazywają to następująco:

-(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; 
} 
2

Najważniejsze jest to, że trzeba zastąpić customTitleView jako tytułViewView:

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 
} 

enter image description here

enter image description here

10

stałej, tworząc jego podklasę UIView i przypisano je do tytułowego związku z panelu nawigacyjnego

Objectve-C:

#import "FLWCustomTitleView.h" 

@implementation FLWCustomTitleView 

- (CGSize)intrinsicContentSize { 
    return UILayoutFittingExpandedSize; 
} 

@end 

enter image description here enter image description here

1

Można również użyć ograniczeń, jeśli nie chcesz, aby zastąpić intrinsicContentSize. Oto demo 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 = ... 
} 

Ale jeśli istnieje więcej niż jeden navigationbaritems na dowolnej stronie (lewej lub prawej) navigationbar, należy użyć intrinsicContentSize;

+0

Czy wiesz, dlaczego potrzebujesz mniej niż 44? Staram się większe bez powodzenia. –

1

Gdy masz UIView jako wyskakujący wewnątrz CustomTitleView, rozwiązanie intrinsicContentSize nie działa, dla mnie w XCODE 9 tylko iOS 11.więc zrobiłem poniżej, działa dobrze dla mnie, może to komuś pomóc.

@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]; 
    } 
} 
0

return UILayoutFittingExpandedSize nie pomógł mi, bo widok dodano pionowo kilka razy, aby napełnić układ.

Roztwór zastąpić intrinsicContentSize w niestandardowej szerokości ustawienie widoku do maksymalnej szerokości ekranu:

- (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; 
} 
4

miałem zmieścić UIImageView jako navigationItem.titleView. Współczynnik proporcji zmieścił się, ale wewnętrzna wartość ContentSize sprawiła, że ​​był duży. Skalowanie obrazu doprowadziło do niskiej jakości obrazu. kotwice układ Ustawienie pracował dla mnie:

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; 
0

Spróbuj użyć Standard UISearchBar/UISearchController

Właściwie to, co trzeba zrobić - jeśli można użyć standardowego UISearchBar/a UISearchController jest wyświetlanie wyszukiwanie bar w następujący sposób, który szanuje bezpieczny obszar, a więc wygląda idealnie na iPhone X i w każdej orientacji urządzenia:

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) 
    } 
} 

Referencje

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

Powiązane problemy