UISearchBar เพิ่มความสูงของแถบนำทางใน iOS 11


89

ฉันUISearchBarเป็นส่วนหนึ่งของแถบนำทางเช่น:

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

หลังจากอัปเดตiOS 11สิ่งแปลก ๆ เกิดขึ้นกับแถบค้นหาในแอปของฉัน ในiOS 10และก่อนหน้านี้ฉันมีแถบนำทางที่มีลักษณะดังนี้:

ป้อนคำอธิบายภาพที่นี่

ตอนนี้iOS 11ฉันมี:

ป้อนคำอธิบายภาพที่นี่

อย่างที่คุณเห็นมีความแตกต่างในการปัดเศษของแถบค้นหาสองแถบซึ่งไม่รบกวนฉัน ปัญหาคือแถบค้นหาเพิ่มความสูงของแถบนำทาง ดังนั้นเมื่อฉันไปที่คอนโทรลเลอร์อื่นมันก็ดูแปลก ๆ เช่นกัน:

ป้อนคำอธิบายภาพที่นี่

ในความเป็นจริงความสูงของเส้นสีดำแปลก ๆ บวกความสูงของแถบนำทางปัจจุบันเท่ากับความสูงของแถบนำทางที่แสดงในภาพที่สอง ...

มีความคิดอย่างไรในการกำจัดเส้นสีดำและมีความสูงของแถบนำทางที่สม่ำเสมอในตัวควบคุมมุมมองทั้งหมดหรือไม่?


อาจซ้ำกันของiOS 11 SearchBar ใน NavigationBar
Jakub Truhlář

คำตอบ:


67

ฉันได้รับเส้นสีดำใต้ NavigationBar พร้อม SearchBar ใน iOS 11 ในสองกรณี:

  • เมื่อฉันผลัก ViewControllers อื่นจาก ViewController ด้วย UISearchBar ป้อนคำอธิบายภาพที่นี่

  • เมื่อฉันปิด ViewController ด้วย UISearchBar ด้วย "ลากไปทางขวาเพื่อปิด" ป้อนคำอธิบายภาพที่นี่

วิธีแก้ปัญหาของฉันคือ: การเพิ่มรหัสนี้ใน ViewController ของฉันด้วย 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
}

อัปเดต 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
ใช้สิ่งนี้ด้วยความระมัดระวังสำหรับฉันมันทำให้แอปทั้งหมดหยุดทำงานเมื่อพยายามปัดกลับไปที่ตัวควบคุมมุมมองที่
บอบบาง

1
การแก้ปัญหานี้ทำให้ฉันโล่งใจมากขอบคุณ @andrew
Sagar Daundkar

67

คุณสามารถเพิ่มข้อ จำกัด ของความสูง 44 ในแถบค้นหาสำหรับ iOS 11

// สวิฟ

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

// วัตถุประสงค์ -C

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

12
แม้ว่าวิธีนี้จะช่วยให้ความสูงกลับมาเป็นปกติ แต่ถ้าฉันแตะที่แถบค้นหาด้วยเหตุผลบางอย่างมันจะตัดส่วนล่างของแถบค้นหาออก มีความคิดเห็นว่าเหตุใดจึงเกิดขึ้นหรือใครก็ตามที่มีปัญหานี้
Christopher Smit

9
ดูแปลก ๆ ถ้าคุณใช้รหัสนี้เพราะแค่ทำให้แถบนำทางแคบลง แต่ความสูงของแถบค้นหายังคงเป็น 56
OtakuFitness

4
มีใครหาวิธีแก้ไขไหม การทำเช่นนี้ก่อให้เกิดปัญหาพฤติกรรมแปลก ๆ มากมายกับแถบค้นหา
Gustavo_fringe

15
นี่ยังไม่เพียงพอคำตอบ พอคลิกที่สนามขนาดยังเลอะ
รอส

5
สิ่งนี้ใช้ไม่ได้ใน iOS 13 วิธีแก้ปัญหาสำหรับสิ่งนี้หรือไม่
VV

42

ฉันเชื่อว่าใน iOS 11 UISearchBar ตอนนี้มีความสูงเท่ากับ 56 แล้วและ UINavigationBar ใช้การจัดวางอัตโนมัติเพื่อให้พอดีกับมุมมองย่อยด้วยเหตุนี้จึงเพิ่มความสูง หากคุณยังต้องการให้ UISearchBar เป็น titleView เหมือนก่อน iOS 11 ฉันพบว่าวิธีที่ดีที่สุดคือการฝัง UISearchBar ในมุมมองที่กำหนดเองและตั้งค่าความสูงของมุมมองนี้เป็น 44 และกำหนดให้กับ 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  
    }  
} 

ทำงานได้อย่างถูกต้อง แต่มีปัญหาเมื่อคุณเปลี่ยนเป็นแนวนอนจากแนวตั้ง
Malav Soni

ทางออกที่ดีหากคุณไม่ได้ใช้รูปแบบอัตโนมัติ จนถึงตอนนี้ดูเหมือนว่าจะใช้งานได้กับโหมดแนวนอนเช่นกันในตัวจำลอง
Ryan H.

ฉันได้โพสต์วิธีแก้ปัญหาที่แก้ไขปัญหาการเปลี่ยนแปลงการวางแนว
de.

คำตอบนี้ช่วยแก้ปัญหาทั้งหมด คำตอบของ zgjie นั้นยอดเยี่ยม แต่กรอบของแถบค้นหายังคงเปลี่ยนไปหลังจากแตะช่องข้อความ
Charlie Hung

19

ลองใช้รหัสนี้บนตัวควบคุมมุมมอง "ACKNOWLEDGMENTS" ใน viewDidLoad

self.extendedLayoutIncludesOpaqueBars = true

ขอบคุณ! นี่คือวิธีแก้ปัญหาที่ฉันลงเอยด้วยการที่ฉันไม่ได้ใช้แท่งโปร่งแสง
mmh02

อันที่จริงนี่ควรเป็นคำตอบ แต่ฉันต้องการเพิ่มที่วางโค้ดนี้ในทั้งคอนโทรลเลอร์ที่อยู่ด้านบนและด้านล่างตัวควบคุมแถบค้นหา
Amrit Sidhu

นั่นใช้ได้ผลสำหรับฉัน แต่ต้องเพิ่ม navigationController? .view.layoutSubviews () ใน viewWillDisappear
douglasd3

สิ่งนี้ได้ผลดีมากฉันจะขอบคุณมากถ้าคุณบอกเราว่ามีextendedLayoutIncludesOpaqueBars ทรัพย์สินอะไรบ้าง
Anirudha Mahale

ExtendedLayoutIncludesOpaqueBars ขยายมุมมองของคุณ (self.view) ภายใต้การนำทางและแถบสถานะ หากคุณเพิ่มมุมมองย่อยลงในมุมมอง (ตัวอย่างเช่น UIImageView) และตั้งค่าข้อ จำกัด ที่ด้านซ้ายบนของมุมมองและเรียกใช้แอปพลิเคชันคุณจะเห็นความแตกต่างเมื่อคุณตั้งค่าคุณสมบัตินี้ระหว่างจริงและเท็จ
Silverwind

7

ขอบคุณทุกคน! ในที่สุดฉันก็พบวิธีแก้ปัญหา

การเพิ่มรหัสต่อไปนี้ใน ViewController ด้วย UISearchBar

  1. ขั้นแรก: viewDidLoad
-(void)viewDidLoad
{
    [super viewDidLoad];
    self.extendedLayoutIncludesOpaqueBars = YES;
    ...
}
override func viewDidLoad() {
    super.viewDidLoad()
    self.extendedLayoutIncludesOpaqueBars = true
}
  1. ขั้นตอนที่สอง: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
    }


2

สิ่งนี้เกิดขึ้นกับฉันเช่นกันทุกอย่างทำงานได้ดีใน iOS 12.4 และแปลกขึ้นใน 13 ด้านบน ปัญหาคือใน iOS 13 ความสูงของแถบนำทางเพิ่มขึ้นจาก 88 เป็น 100 หลังจากกระโดดจาก UIViewController ที่ใช้ searchBar

ลองใช้สิ่งนี้ใน UIViewController ของคุณที่ใช้ searchBar

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

ดูตัวอย่างหลังจากแก้ไข:

ป้อนคำอธิบายภาพที่นี่ ป้อนคำอธิบายภาพที่นี่

ดูตัวอย่างก่อนแก้ไข:

ป้อนคำอธิบายภาพที่นี่ ป้อนคำอธิบายภาพที่นี่


1

แก้ไข: คำตอบ @zgjie เป็นทางออกที่ดีกว่าสำหรับปัญหานี้: https://stackoverflow.com/a/46356265/1713123

ดูเหมือนว่าจะเกิดขึ้นเนื่องจากใน iOS 11 ค่าความสูงเริ่มต้นของ SearchBar เปลี่ยนเป็น 56 แทนที่จะเป็น 44 ใน iOS เวอร์ชันก่อนหน้า

ในตอนนี้ฉันได้ใช้วิธีแก้ปัญหานี้โดยตั้งค่าความสูงของแถบค้นหากลับไปที่ 44:

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

อีกวิธีหนึ่งสามารถใช้คุณสมบัติ searchController ใหม่บน navigationItem ใน iOS 11 :

navigationItem.searchController = searchController

แต่วิธีนี้ da searchBar จะปรากฏด้านล่างชื่อการนำทาง


1
การเปลี่ยนแปลงได้รับการบันทึกไว้ที่ไหนสักแห่งไหม ฉันไม่สามารถหาได้ที่นี่
Iulian Onofrei

1
FYI คุณสามารถปรับเปลี่ยนเฟรมได้โดยไม่ต้องสร้างตัวแปร CGRect().insetBy(dx:dy:)และCGRect().offsetBy(dx:dy:)ในกรณีนี้ -searchController.searchBar.frame = searchController.searchBar.frame.insetBy(dx: 0, dy: -12)
Oscar Apeland

วิธีนี้ใช้ได้ผล แต่เมื่อคุณคลิกแถบค้นหาความสูงจะถูกรีเซ็ต
Gustavo_fringe

@Gustavo_fringe คุณพบวิธีแก้ปัญหานี้หรือไม่
Shivam Pokhriyal

1

วิธีแก้ปัญหาทั้งหมดไม่ได้ผลสำหรับฉันก่อนที่ฉันจะผลักตัวควบคุมมุมมองฉันทำ:

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

    self.navigationItem.titleView = UIView()
}

และเพื่อให้แถบค้นหาปรากฏขึ้นเมื่อย้อนกลับ:

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

    self.navigationItem.titleView = UISearchBar()
}

สิ่งนี้ลบมุมมองสีดำในตัวควบคุมมุมมองใหม่ แต่เมื่อกลับไปที่ตัวควบคุมมุมมองนี้ (อันที่มี searchBar) รูทวิวก็ขยับขึ้นเล็กน้อย
code4latte

1

ฉันไม่สามารถใช้วิธีการรักษา navBar ที่ 44 ได้ดังนั้นฉันจึงใช้เวลาหนึ่งวัน แต่ในที่สุดฉันก็พบวิธีแก้ปัญหาที่ไม่เปลี่ยนความสูงของแท่งและวางปุ่มไว้ตรงกลางของแถบ ปัญหาคือปุ่มต่างๆถูกวางไว้ในมุมมองสแต็กซึ่งกำหนดค่าเป็นมุมมองสแต็กแนวนอนดังนั้นจึงไม่ปรับตามการเปลี่ยนแปลงความสูง

สิ่งนี้ทำได้ใน 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)];
}

บน viewWillApear (หรือทุกเวลาหลังจากเพิ่มมุมมองไปยังสแตกการนำทาง)

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

และ subviewOfClass เป็นหมวดหมู่บน 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

สิ่งที่คุณต้องทำคือซับคลาส UISearchBar และแทนที่ "intrinsicContentSize":

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

ป้อนคำอธิบายภาพที่นี่


1

ไม่สามารถแสดงความคิดเห็นได้ แต่ต้องการแบ่งปันปัญหาเพิ่มเติมบางอย่างที่ฉันพบในขณะที่ใช้เวลาหลายชั่วโมงในการพยายามแก้ไขปัญหานี้แม้ว่าจะใช้วิธีแก้ปัญหาอื่น ๆ แล้วก็ตาม

ดูเหมือนว่าการแก้ไขที่ดีที่สุดสำหรับฉันคือคำตอบของ 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
}

อย่างไรก็ตามอย่างน้อยที่สุดใน iOS 12.1หากคุณUINavigationBar:

  • ได้isTranslucentตั้งค่าfalseเป็น View Controller พร้อมแถบค้นหาดูเหมือนจะไม่ได้รับการปรับเปลี่ยนเค้าโครงของมุมมองเมื่อปิดการโต้ตอบ (การปิดตามปกติผ่านปุ่มย้อนกลับดูเหมือนจะใช้งานได้)
  • มีการตั้งค่าภาพพื้นหลังโดยใช้setBackgroundImage(UIImage(), for: .default)ภาพเคลื่อนไหวการเปลี่ยนแปลงทำงานไม่ถูกต้องและจะกลับไปที่ตำแหน่งหลังจากเสร็จสิ้น

คุณสมบัติเฉพาะเหล่านี้ได้รับการตั้งค่าเพื่อให้แถบนำทางปรากฏในลักษณะใดวิธีหนึ่งดังนั้นฉันต้องปรับเปลี่ยนบางอย่างเพื่อเอากลับคืนมาหรือทนกับพฤติกรรมแปลก ๆ จะพยายามอย่าลืมอัปเดตข้างต้นหากฉันพบสิ่งอื่นใดหรือพบวิธีแก้ปัญหาหรือความแตกต่างอื่น ๆ ในระบบปฏิบัติการเวอร์ชันอื่น


0

ในกรณีของฉันความสูงของ UINavigationBar ที่ใหญ่ขึ้นไม่ใช่ปัญหาสำหรับฉัน ฉันแค่ต้องการจัดรูปแบบรายการปุ่มแถบซ้ายและขวา นั่นเป็นวิธีแก้ปัญหาที่ฉันคิดขึ้น:

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

โดยทั่วไปเราค้นหามุมมองสแต็กที่มีรายการปุ่มแถบแล้วเปลี่ยนค่าข้อ จำกัด ด้านบนและด้านล่าง ใช่มันเป็นการแฮ็กที่สกปรกและจะไม่แนะนำให้ใช้หากคุณสามารถแก้ไขปัญหาได้ด้วยวิธีอื่น


ฉันอยากทำแบบเดียวกับคุณ แต่ฉันจะรอจนกว่าจะมีทางออกที่ดีกว่านี้ ขอบคุณสำหรับการแบ่งปันต่อไป
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

ฉันพบว่าวิธีแก้ปัญหาของ Mai Mai เป็นวิธีเดียวที่ใช้งานได้จริง
อย่างไรก็ตามมันยังไม่สมบูรณ์แบบ:
เมื่อหมุนอุปกรณ์แถบค้นหาจะไม่ได้รับการปรับขนาดอย่างเหมาะสมและยังคงอยู่ในขนาดที่เล็กกว่า

ฉันพบวิธีแก้ไขแล้ว นี่คือรหัสของฉันใน Objective C ที่มีส่วนที่เกี่ยวข้องมีคำอธิบายประกอบ:

// 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

ตอนนี้ยังเหลืออีกหนึ่งกรณีที่ฉันยังไม่ได้คิดออก ในการทำซ้ำให้ทำดังต่อไปนี้:
- เริ่มในแนวตั้ง
- เปิดใช้งานช่องค้นหา
- หมุนเป็นแนวนอน
- ข้อผิดพลาด: แถบไม่ปรับขนาด


0

ฉันแก้ไขสิ่งนี้โดยเพิ่มข้อ จำกัด ให้กับ viewDidAppear บนตัวควบคุมมุมมองแผนที่ที่ฝังแถบค้นหา

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
คุณขาดการโทรของ super.viewDidAppear (ภาพเคลื่อนไหว)
Reconquistador

0

สวัสดีสำหรับคนที่ใช้UISearchControllerและแนบUISearchBarไปกับnavigationItem.titleView. ฉันใช้เวลาบ้าๆ 4-5 ชั่วโมงในแต่ละวันเพื่อแก้ปัญหานี้ ปฏิบัติตามแนวทางที่แนะนำสำหรับ iOS 11+ ซึ่งนำsearchControllerไปสู่navigation.searchControllerนั้นไม่เหมาะกับกรณีของฉัน หน้าจอที่มี searchController / searchBar นี้มี backButton ซึ่งเป็นแบบกำหนดเอง

ฉันได้ทดสอบสิ่งนี้ใน iOS 10, iOS 11 และ 12 ในอุปกรณ์ต่างๆ ฉันแค่ต้อง ฉันไม่สามารถกลับบ้านได้โดยไม่ต้องแก้ปีศาจนี้ นี่เป็นสิ่งที่สมบูรณ์แบบที่สุดที่ฉันสามารถทำได้ในวันนี้เนื่องจากกำหนดเวลาที่แน่นหนาของฉัน

ดังนั้นฉันแค่อยากจะแบ่งปันการทำงานหนักนี้ที่ฉันทำขึ้นอยู่กับคุณที่จะใส่ทุกอย่างลงในที่ที่คุณต้องการ (เช่นตัวแปรใน viewModel ของคุณ) นี่คือ:

ในหน้าจอแรกของฉัน (พูดว่าหน้าจอหลักที่ไม่มีตัวควบคุมการค้นหานี้) ฉันมีสิ่งนี้ในviewDidLoad()ไฟล์.

self.extendedLayoutIncludesOpaqueBars = true

ในหน้าจอที่สองของฉันหน้าจอที่มี searchController ฉันมีสิ่งนี้ใน viewDidAppear .

แทนที่ func viewDidAppear (_ ภาพเคลื่อนไหว: Bool) {super.viewDidAppear (ภาพเคลื่อนไหว)

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

และนี่คือคำประกาศของ SearchController ของฉัน:

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

ฉันหวังว่าสิ่งนี้จะช่วยใครสักคนได้ในสักวัน


-1

ฉันลองทำหลาย ๆ อย่างเพื่อให้ขนาดกลับไปเป็น 44 เดิม แต่แถบค้นหามักจะดูและทำตัวแปลก ๆ - เหมือนอยู่ไกล ๆ , y-offset และเหมือนกัน

ฉันพบทางออกที่ดีที่นี่ (ผ่านโพสต์ stackoverflow อื่น ๆ ): https://github.com/DreamTravelingLight/searchBarDemo

เพียงรับ viewcontroller ของคุณจาก SearchViewController และรวมคลาส SearchViewController และ WMSearchbar ไว้ในโปรเจ็กต์ของคุณ ทำงานนอกกรอบให้ฉันโดยไม่น่าเกลียดถ้า (iOS11) อื่น ...


-1

ในกรณีของฉันฉันต้องลดความสูงของ textField 36pt -> 28pt

ป้อนคำอธิบายภาพที่นี่

ผมจึงพยายามเปลี่ยนความสูงของเฟรมความสูงของเลเยอร์ แต่วิธีต่างๆไม่ได้ผล

ในที่สุดฉันก็พบวิธีแก้ปัญหานั่นคือหน้ากาก ฉันคิดว่ามันไม่ใช่วิธีที่ดี แต่ได้ผล

    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
    }

คุณสามารถเปลี่ยนสิ่งที่ใส่เข้าไปได้หากคุณต้องการเปลี่ยนกรอบของ textField

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.