UISearchBar zwiększa wysokość paska nawigacji w iOS 11


89

Jestem UISearchBarczęścią paska nawigacyjnego, takiego jak:

 let searchBar = UISearchBar()
 //some more configuration to the search bar
 .....
 navigationItem.titleView = searchBar

Po aktualizacji do iOS 11czegoś dziwnego stało się z paskiem wyszukiwania w mojej aplikacji. On iOS 10i przed miałem pasek nawigacji wyglądające jak:

wprowadź opis obrazu tutaj

Teraz iOS 11mam:

wprowadź opis obrazu tutaj

Jak widać, istnieje różnica w zaokrągleniu dwóch pasków wyszukiwania, co mi nie przeszkadza. Problem w tym, że pasek wyszukiwania zwiększa wysokość paska nawigacji. Więc kiedy idę do innego kontrolera, też wygląda to dziwnie:

wprowadź opis obrazu tutaj

W rzeczywistości ta dziwna wysokość czarnej linii plus aktualna wysokość paska nawigacji jest równa wysokości paska nawigacji pokazanego na drugim obrazku ...

Jakieś pomysły, jak pozbyć się czarnej linii i mieć spójną wysokość paska nawigacji we wszystkich kontrolerach widoku?


Możliwy duplikat
paska wyszukiwania

Odpowiedzi:


66

Mam czarną linię pod NavigationBar z SearchBar w iOS 11 w dwóch przypadkach:

  • kiedy pchnąłem kolejne ViewControllers z ViewController z UISearchBar wprowadź opis obrazu tutaj

  • kiedy zamknąłem ViewController z UISearchBar z „przeciągnij w prawo, aby odrzucić” wprowadź opis obrazu tutaj

Moje rozwiązanie brzmiało: dodanie tego kodu do mojego ViewController za pomocą UISearchBar:

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self.navigationController.view setNeedsLayout]; // force update layout
    [self.navigationController.view layoutIfNeeded]; // to fix height of the navigation bar
}

Aktualizacja Swift 4

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    navigationController?.view.setNeedsLayout() // force update layout
    navigationController?.view.layoutIfNeeded() // to fix height of the navigation bar
}

2
Używaj tego ostrożnie, ponieważ dla mnie cała aplikacja zawiesiła się, gdy próbowano przesunąć z powrotem do poprzedniego kontrolera widoku
Abd Al-rhman Taher Badary

1
To rozwiązanie naprawdę dało mi dużą ulgę dzięki @andrew
Sagar Daundkar

67

Możesz dodać ograniczenie wysokości 44 do paska wyszukiwania dla iOS 11.

// Swift

if #available(iOS 11.0, *) {
    searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true
}

// Cel C

if (@available(iOS 11.0, *)) {
    [searchBar.heightAnchor constraintEqualToConstant:44].active = YES;
}

12
Chociaż działa to w celu przywrócenia normalnej wysokości, jeśli stuknę w pasek wyszukiwania, z jakiegoś powodu odcina dolną część paska wyszukiwania. Jakieś pomysły, dlaczego tak się dzieje lub ktoś inny ma ten problem?
Christopher Smit,

9
Zupełnie dziwnie wygląda, jeśli używasz tego kodu, ponieważ po prostu zawęża pasek nawigacji, ale wysokość paska wyszukiwania wciąż wynosi 56.
OtakuFitness

4
Czy ktoś inny znalazł rozwiązanie? robienie tego powoduje wiele dziwnych problemów behawioralnych z paskiem wyszukiwania.
Gustavo_fringe

15
To nie jest wystarczająca odpowiedź. Po kliknięciu pola rozmiar jest nadal pomieszany.
Ross

5
To nie działa w iOS 13. Jakieś obejście tego problemu?
VV

42

Wierzę, że UISearchBar w iOS 11 ma teraz wysokość równą 56, a UINavigationBar używa autolayout, aby dopasować jego podwidoki, dlatego zwiększa wysokość. Jeśli nadal chcesz mieć UISearchBar jako titleView, tak jak w wersji przed iOS 11, odkryłem, że najlepszym sposobem na to jest osadzenie UISearchBar w niestandardowym widoku i ustawienie wysokości tego widoku na 44 i przypisanie go do navigationItem.titleView

class SearchBarContainerView: UIView {  

    let searchBar: UISearchBar  

    init(customSearchBar: UISearchBar) {  
        searchBar = customSearchBar  
        super.init(frame: CGRect.zero)  

        addSubview(searchBar)  
    }

    override convenience init(frame: CGRect) {  
        self.init(customSearchBar: UISearchBar())  
        self.frame = frame  
    }  

    required init?(coder aDecoder: NSCoder) {  
        fatalError("init(coder:) has not been implemented")  
    }  

    override func layoutSubviews() {  
        super.layoutSubviews()  
        searchBar.frame = bounds  
    }  
}  

class MyViewController: UIViewController {  

    func setupNavigationBar() {  
        let searchBar = UISearchBar()  
        let searchBarContainer = SearchBarContainerView(customSearchBar: searchBar)  
        searchBarContainer.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44)  
        navigationItem.titleView = searchBarContainer  
    }  
} 

Działa to poprawnie, ale pojawia się problem po zmianie na poziomą z pionowej.
Malav Soni

Świetne rozwiązanie, jeśli nie używasz automatycznego układu. Jak dotąd wydaje się, że działa to również w trybie poziomym w symulatorze.
Ryan H.

Opublikowałem rozwiązanie, które rozwiązuje problemy ze zmianą orientacji.
de.

Ta odpowiedź rozwiązała wszystkie problemy. Odpowiedź zgjie jest świetna, ale ramka paska wyszukiwania nadal się zmieniała po dotknięciu pola tekstowego.
Charlie Hung

19

wypróbuj ten kod na kontrolerze widoku „ACKNOWLEDGMENTS” w viewDidLoad

self.extendedLayoutIncludesOpaqueBars = true

Dzięki! To jest rozwiązanie, które ostatecznie wybrałem, ponieważ nie używam półprzezroczystych pasków.
mmh02

Rzeczywiście, powinna to być odpowiedź. Ale chciałbym dodać, że umieść ten fragment kodu zarówno w kontrolerze, który znajduje się nad i pod kontrolerem paska wyszukiwania.
Amrit Sidhu,

To zadziałało dla mnie, ale musiałem dodać navigationController? .View.layoutSubviews () w viewWillDisappear.
douglasd3

To działa bardzo dobrze, byłbym wdzięczny, gdybyś powiedział nam, czym extendedLayoutIncludesOpaqueBars zajmuje się nieruchomość.
Anirudha Mahale,

extendedLayoutIncludesOpaqueBars rozwiń swój widok (self.view) pod paskiem nawigacji i stanu. Jeśli dodasz widok podrzędny do widoku (na przykład UIImageView) i ustawisz jego ograniczenie w lewym górnym rogu widoku i uruchomisz aplikację, zobaczysz różnicę po ustawieniu tej właściwości między wartością true i false.
Silverwind

6

Dziękuję wam wszystkim! W końcu znalazłem rozwiązanie.

Dodanie następującego kodu do ViewController za pomocą UISearchBar.

  1. Pierwszy krok: viewDidLoad
-(void)viewDidLoad
{
    [super viewDidLoad];
    self.extendedLayoutIncludesOpaqueBars = YES;
    ...
}
override func viewDidLoad() {
    super.viewDidLoad()
    self.extendedLayoutIncludesOpaqueBars = true
}
  1. Drugi krok:viewWillDisappear
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
     // force update layout
    [self.navigationController.view setNeedsLayout]; 
    // to fix height of the navigation bar
    [self.navigationController.view layoutIfNeeded];  
}
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        navigationController?.view.setNeedsLayout() // force update layout
        navigationController?.view.layoutIfNeeded() // to fix height of the navigation bar
    }

4

W celu-C

if (@available(iOS 11.0, *)) {
        [self.searchBar.heightAnchor constraintLessThanOrEqualToConstant: 44].active = YES;
}              

2

Mnie też się to zdarza, wszystko działa dobrze w iOS 12.4 i robi się dziwnie w 13 powyżej. Problem polega na wzroście wysokości paska nawigacji iOS 13 z 88 do 100 po skoku z UIViewController, który implementuje searchBar.

Wypróbuj to w swoim UIViewController, który implementuje searchBar.

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    navigationController?.view.setNeedsLayout()
    navigationController?.view.layoutIfNeeded()
}

Podgląd po naprawie:

wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj

Podgląd przed naprawą:

wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj


1

EDYTUJ: Odpowiedź @zgjie jest lepszym rozwiązaniem tego problemu: https://stackoverflow.com/a/46356265/1713123

Wygląda na to, że dzieje się tak, ponieważ w iOS 11 domyślna wartość wysokości SearchBar została zmieniona na 56, zamiast 44 w poprzednich wersjach iOS.

Na razie zastosowałem to obejście, ustawiając wysokość searchBar z powrotem na 44:

let barFrame = searchController.searchBar.frame
searchController.searchBar.frame = CGRect(x: 0, y: 0, width: barFrame.width, height: 44)    

Innym rozwiązaniem mogłoby być użycie nowej właściwości searchController w navigationItem w iOS 11 :

navigationItem.searchController = searchController

Ale w ten sposób da searchBar pojawia się pod tytułem nawigacji.


1
Czy zmiana jest gdzieś udokumentowana? Nie mogłem go tu znaleźć .
Iulian Onofrei

1
FYI, możesz zmodyfikować ramkę bez tworzenia dla niej zmiennej; CGRect().insetBy(dx:dy:)aw CGRect().offsetBy(dx:dy:)tym przypadku -searchController.searchBar.frame = searchController.searchBar.frame.insetBy(dx: 0, dy: -12)
Oscar Apeland

To rozwiązanie zadziałało, ale po kliknięciu paska wyszukiwania wysokość jest resetowana.
Gustavo_fringe

@Gustavo_fringe Czy znalazłeś na to jakieś rozwiązanie.
Shivam Pokhriyal,

1

Całe rozwiązanie nie działało dla mnie, więc zanim pchnąłem kontroler widoku, zrobiłem:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    self.navigationItem.titleView = UIView()
}

Aby wyświetlić pasek wyszukiwania podczas cofania:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    self.navigationItem.titleView = UISearchBar()
}

Spowodowało to usunięcie czarnego widoku w nowym kontrolerze widoku, ale po powrocie do tego kontrolera widoku (tego, który zawiera element searchBar), widok rootView faktycznie przesunął się nieco w górę.
code4latte

1

Nie mogłem skorzystać z rozwiązania polegającego na utrzymaniu navBara na 44. Więc zajęło mi to dzień, ale w końcu znalazłem rozwiązanie, które nie zmienia wysokości paska i umieszcza przycisk na środku paska. Problem polega na tym, że przyciski są umieszczane w widoku stosu, który jest skonfigurowany jako poziomy widok stosu i dlatego nie dostosowuje się do zmiany wysokości.

Odbywa się to na init:

UIBarButtonItem *cancelButton;
if (@available(iOS 11.0, *)) {
    // For iOS11 creating custom button to accomadate the change of navbar + search bar being 56 points
    self.navBarCustomButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.navBarCustomButton setTitle:@"Cancel"];
    [self.navBarCustomButton addTarget:self action:@selector(cancelButtonTapped) forControlEvents:UIControlEventTouchUpInside];
    cancelButton = [[UIBarButtonItem alloc] initWithCustomView:self.navBarCustomButton];
} else {
    cancelButton = [[UIBarButtonItem alloc] initWithTitle:MagicLocalizedString(@"button.cancel", @"Cancel")
                                                                                         style:UIBarButtonItemStylePlain
                                                                                        target:self
                                                                                        action:@selector(cancelButtonTapped)];
}

on viewWillApear (lub w dowolnym momencie po dodaniu widoku do stosu nawigacji)

   if (@available(iOS 11.0, *)) {
        UIView *buttonsStackView = [navigationController.navigationBar subviewOfClass:[UIStackView class]];
        if (buttonsStackView ) {
            [buttonsStackView.centerYAnchor constraintEqualToAnchor:navigationController.navigationBar.centerYAnchor].active = YES;
            [self.navBarCustomButton.heightAnchor constraintEqualToAnchor:buttonsStackView.heightAnchor];
        }
    }

A subviewOfClass to kategoria w UIView:

- (__kindof UIView *)subviewOfClass:(Class)targetClass {
     // base case
     if ([self isKindOfClass:targetClass]) {
        return self;
     }

     // recursive
    for (UIView *subview in self.subviews) {
        UIView *dfsResult = [subview subviewOfClass:targetClass];

        if (dfsResult) {
           return dfsResult;
       }
   }
   return nil;
}

1

Wszystko, co musisz zrobić, to utworzyć podklasę UISearchBar i zastąpić wartość „intrinsicContentSize”:

@implementation CJSearchBar
-(CGSize)intrinsicContentSize{
    CGSize s = [super intrinsicContentSize];
    s.height = 44;
    return s;
}
@end

wprowadź opis obrazu tutaj


1

Nie można komentować, ale chciałem podzielić się kilkoma dodatkowymi problemami, na które napotkałem, spędzając wiele godzin, próbując dotrzeć do sedna tego problemu, nawet po zastosowaniu jednego z innych rozwiązań.

Wydaje się, że najlepszym rozwiązaniem dla mnie była odpowiedź Andrew :

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    navigationController?.view.setNeedsLayout() // force update layout
    navigationController?.view.layoutIfNeeded() // to fix height of the navigation bar
}

Jednak przynajmniej w iOS 12.1 , jeśli UINavigationBar:

  • został isTranslucentustawiony nafalse , widok z kontrolera pojawi się pasek wyszukiwania, aby nie dać się dostosować układ kopię widoku, gdy interaktywnie odwoływanie (normalny odwoływanie poprzez pojawi się przycisk z powrotem do pracy).
  • ma ustawiony obraz tła za pomocą setBackgroundImage(UIImage(), for: .default), animacja przejścia nie działa poprawnie i po zakończeniu wróci do swojej pozycji.

Te szczególne właściwości zostały ustawione tak, aby pasek nawigacji pojawiał się w określony sposób, więc muszę trochę dostosować, aby go odzyskać lub znosić dziwne zachowanie. Postaram się pamiętać, aby zaktualizować powyższe, jeśli napotkam coś innego lub znajdę inne rozwiązania lub różnice w innych wersjach systemu operacyjnego.


0

W moim przypadku większa wysokość UINavigationBar nie była dla mnie problemem. Musiałem tylko ponownie wyrównać lewy i prawy przycisk paska. Oto rozwiązanie, które wymyśliłem:

- (void)iOS11FixNavigationItemsVerticalAlignment
{
    [self.navigationController.navigationBar layoutIfNeeded];

    NSString * currSysVer = [[UIDevice currentDevice] systemVersion];
    if ([currSysVer compare:@"11" options:NSNumericSearch] != NSOrderedAscending)
    {
        UIView * navigationBarContentView;
        for (UIView * subview in [self.navigationController.navigationBar subviews])
        {
            if ([subview isKindOfClass:NSClassFromString(@"_UINavigationBarContentView")])
            {
                navigationBarContentView = subview;
                break;
            }
        }

        if (navigationBarContentView)
        {
            for (UIView * subview in [navigationBarContentView subviews])
            {
                if (![subview isKindOfClass:NSClassFromString(@"_UIButtonBarStackView")]) continue;

                NSLayoutConstraint * topSpaceConstraint;
                NSLayoutConstraint * bottomSpaceConstraint;

                CGFloat topConstraintMultiplier = 1.0f;
                CGFloat bottomConstraintMultiplier = 1.0f;

                for (NSLayoutConstraint * constraint in navigationBarContentView.constraints)
                {
                    if (constraint.firstItem == subview && constraint.firstAttribute == NSLayoutAttributeTop)
                    {
                        topSpaceConstraint = constraint;
                        break;
                    }

                    if (constraint.secondItem == subview && constraint.secondAttribute == NSLayoutAttributeTop)
                    {
                        topConstraintMultiplier = -1.0f;
                        topSpaceConstraint = constraint;
                        break;
                    }
                }

                for (NSLayoutConstraint * constraint in navigationBarContentView.constraints)
                {
                    if (constraint.firstItem == subview && constraint.firstAttribute == NSLayoutAttributeBottom)
                    {
                        bottomSpaceConstraint = constraint;
                        break;
                    }

                    if (constraint.secondItem == subview && constraint.secondAttribute == NSLayoutAttributeBottom)
                    {
                        bottomConstraintMultiplier = -1.0f;
                        bottomSpaceConstraint = constraint;
                        break;
                    }
                }

                CGFloat contentViewHeight = navigationBarContentView.frame.size.height;
                CGFloat subviewHeight = subview.frame.size.height;
                topSpaceConstraint.constant = topConstraintMultiplier * (contentViewHeight - subviewHeight) / 2.0f;
                bottomSpaceConstraint.constant = bottomConstraintMultiplier * (contentViewHeight - subviewHeight) / 2.0f;
            }
        }
    }
}

Zasadniczo wyszukujemy widoki stosu, które zawierają elementy przycisków paska, a następnie zmieniamy ich górne i dolne wartości ograniczeń. Tak, to brudny hack i nie polecam go używać, jeśli możesz rozwiązać problem w inny sposób.


Chcę zrobić to samo co Ty, ale poczekam, aż pojawi się bardziej eleganckie rozwiązanie. Mimo wszystko dzięki za udostępnienie.
Michael Pirotte,

0
//
//  Created by Sang Nguyen on 10/23/17.
//  Copyright © 2017 Sang. All rights reserved.
//

import Foundation
import UIKit

class CustomSearchBarView: UISearchBar {
    final let SearchBarHeight: CGFloat = 44
    final let SearchBarPaddingTop: CGFloat = 8
    override open func awakeFromNib() {
        super.awakeFromNib()
        self.setupUI()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setupUI()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
       // fatalError("init(coder:) has not been implemented")
    }
    func findTextfield()-> UITextField?{
        for view in self.subviews {
            if view is UITextField {
                return view as? UITextField
            } else {
                for textfield in view.subviews {
                    if textfield is UITextField {
                        return textfield as? UITextField
                    }
                }
            }
        }
        return nil;
    }
    func setupUI(){
        if #available(iOS 11.0, *) {
            self.translatesAutoresizingMaskIntoConstraints = false
            self.heightAnchor.constraint(equalToConstant: SearchBarHeight).isActive = true
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        if #available(iOS 11.0, *) {
            if let textfield = self.findTextfield() {
                textfield.frame = CGRect(x: textfield.frame.origin.x, y: SearchBarPaddingTop, width: textfield.frame.width, height: SearchBarHeight - SearchBarPaddingTop * 2)`enter code here`
                return
            }
        }
    }
}

0

Uważam, że rozwiązanie Mai Mai jest jedynym, które jest naprawdę użyteczne.
Jednak nadal nie jest idealny:
podczas obracania urządzenia pasek wyszukiwania nie jest odpowiednio zmieniany i pozostaje w mniejszym wymiarze.

Znalazłem na to rozwiązanie. Oto mój kod w Objective C z adnotacjami dotyczącymi odpowiednich części:

// improvements in the search bar wrapper
@interface SearchBarWrapper : UIView
@property (nonatomic, strong) UISearchBar *searchBar;
- (instancetype)initWithSearchBar:(UISearchBar *)searchBar;
@end
@implementation SearchBarWrapper
- (instancetype)initWithSearchBar:(UISearchBar *)searchBar {
    // setting width to a large value fixes stretch-on-rotation
    self = [super initWithFrame:CGRectMake(0, 0, 4000, 44)];
    if (self) {
        self.searchBar = searchBar;
        [self addSubview:searchBar];
    }
    return self;
}
- (void)layoutSubviews {
    [super layoutSubviews];
    self.searchBar.frame = self.bounds;
}
// fixes width some cases of resizing while search is active
- (CGSize)sizeThatFits:(CGSize)size {
    return size;
}
@end

// then use it in your VC
@implementation MyViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.titleView = [[SearchBarWrapper alloc] initWithSearchBar:self.searchController.searchBar];
}
@end

Pozostał jeszcze jeden przypadek, którego jeszcze nie rozgryzłem. Aby odtworzyć, wykonaj następujące czynności:
- zacznij w pionie
- aktywuj pole wyszukiwania
- obróć do pozycji poziomej
- błąd: pasek nie zmienia rozmiaru


0

Naprawiłem to, dodając ograniczenie do viewDidAppear na kontrolerze widoku mapy, w którym osadzony jest pasek wyszukiwania

public override func viewDidAppear(_ animated: Bool) {
    if #available(iOS 11.0, *) {

        resultSearchController?.searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true
        // searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true
    }
}

1
Brakuje Ci wywołania super.viewDidAppear (animowanego)
Reconquistador

0

Witam ludzi, którzy używają, UISearchControllera następnie dołączają go UISearchBardo navigationItem.titleView. Spędziłem szalone 4-5 godzin dnia, aby rozwiązać ten problem. Po iOS 11+ zalecane podejście, które jest oddanie searchControllerdo navigation.searchControllernie znajduje się tuż za moim przypadku. Ekran, na którym jest to searchController / searchBar, ma niestandardowy backButton.

Przetestowałem to w iOS 10, iOS 11 i 12. Na różnych urządzeniach. Po prostu musiałem. Nie mogę wrócić do domu bez rozwiązania tego demona. To najdoskonalszy, jaki mogłem zrobić dzisiaj, biorąc pod uwagę mój napięty termin.

Więc chcę tylko podzielić się tą ciężką pracą, którą wykonałem, to od Ciebie zależy, czy umieścisz wszystko tam, gdzie chcesz (np. Zmienne w Twoim ViewModel). Oto jest:

Na moim pierwszym ekranie (powiedzmy ekranie głównym, który nie ma tego kontrolera wyszukiwania), mam to w moim viewDidLoad().

self.extendedLayoutIncludesOpaqueBars = true

Na moim drugim ekranie, tym, który ma searchController, mam to w moim viewDidAppear.

override func viewDidAppear (_ animated: Bool) {super.viewDidAppear (animated)

    let systemMajorVersion = ProcessInfo.processInfo.operatingSystemVersion.majorVersion
    if systemMajorVersion < 12 {
        // Place the search bar in the navigation item's title view.
        self.navigationItem.titleView = self.searchController.searchBar
    }

    if systemMajorVersion >= 11 {

        self.extendedLayoutIncludesOpaqueBars = true

        UIView.animate(withDuration: 0.3) {
            self.navigationController?.navigationBar.setNeedsLayout()
            self.navigationController?.navigationBar.layoutIfNeeded()
        }

        self.tableView.contentInset = UIEdgeInsets(top: -40, left: 0, bottom: 0, right: 0)

        if self.viewHadAppeared {
            self.tableView.contentInset = .zero
        }
    }

    self.viewHadAppeared = true // this is set to false by default.
}

a oto moja deklaracja searchControllera:

lazy var searchController: UISearchController = {
    let searchController = UISearchController(searchResultsController: nil)
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.dimsBackgroundDuringPresentation = false
    searchController.searchBar.textField?.backgroundColor = .lalaDarkWhiteColor
    searchController.searchBar.textField?.tintColor = .lalaDarkGray
    searchController.searchBar.backgroundColor = .white
    return searchController
}()

Mam więc nadzieję, że to kiedyś komuś pomoże.


-1

Próbowałem różnych rzeczy, aby przywrócić rozmiar do pierwotnego 44, ale pasek wyszukiwania zawsze wygląda i zachowuje się dziwnie - jak zbyt daleko rozciągnięty, przesunięty w osi Y i podobnie.

Znalazłem tutaj fajne rozwiązanie (przez inny post stackoverflow): https://github.com/DreamTravelingLight/searchBarDemo

Po prostu wyprowadź swój viewcontroller z SearchViewController i dołącz do projektu klasy SearchViewController i WMSearchbar. Zadziałało dla mnie po wyjęciu z pudełka bez brzydkiego, gdyby (iOS11) innego ... brzydoty.


-1

W moim przypadku muszę zmniejszyć wysokość textField o 36pt -> 28pt.

wprowadź opis obrazu tutaj

Próbowałem więc zmienić wysokość ramki, wysokość warstwy. Ale sposoby nie działały.

Wreszcie znalazłem rozwiązanie, którym jest maska. Myślę, że to nie jest dobry sposób, ale działa.

    let textField              = searchBar.value(forKey: "searchField") as? UITextField
    textField?.font            = UIFont.systemFont(ofSize: 14.0, weight: .regular)
    textField?.textColor       = #colorLiteral(red: 0.1960784314, green: 0.1960784314, blue: 0.1960784314, alpha: 1)
    textField?.textAlignment   = .left

    if #available(iOS 11, *) {
        let radius: CGFloat           = 5.0
        let magnifyIconWidth: CGFloat = 16.0
        let inset                     = UIEdgeInsets(top: 4.0, left: 0, bottom: 4.0, right: 0)

        let path = CGMutablePath()
        path.addArc(center: CGPoint(x: searchBar.bounds.size.width - radius - inset.right - magnifyIconWidth, y: inset.top + radius), radius: radius, startAngle: .pi * 3.0/2.0, endAngle: .pi*2.0, clockwise: false)                        // Right top
        path.addArc(center: CGPoint(x: searchBar.bounds.size.width - radius - inset.right - magnifyIconWidth, y: searchBar.bounds.size.height - radius - inset.bottom), radius: radius, startAngle: 0, endAngle: .pi/2.0, clockwise: false)  // Right Bottom
        path.addArc(center: CGPoint(x: inset.left + radius, y: searchBar.bounds.size.height - radius - inset.bottom), radius: radius, startAngle: .pi/2.0, endAngle: .pi, clockwise: false)                                                  // Left Bottom
        path.addArc(center: CGPoint(x: inset.left + radius, y: inset.top + radius),  radius: radius, startAngle: .pi, endAngle: .pi * 3.0/2.0, clockwise: false)                                                                             // Left top

        let maskLayer      = CAShapeLayer()
        maskLayer.path     = path
        maskLayer.fillRule = kCAFillRuleEvenOdd

        textField?.layer.mask = maskLayer
    }

Możesz zmienić wstawki, jeśli chcesz zmienić ramkę textField.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.