ฉันจะเปลี่ยนสีข้อความค้นหา UISearchBar ได้อย่างไร?


คำตอบ:


108

คุณต้องเข้าไปที่UITextFieldด้านใน UISearchBar คุณสามารถทำได้โดยใช้valueForKey("searchField")

var textFieldInsideSearchBar = yourSearchbar.valueForKey("searchField") as? UITextField

textFieldInsideSearchBar?.textColor = yourcolor

อัปเดต Swift 3

let textFieldInsideSearchBar = yourSearchbar.value(forKey: "searchField") as? UITextField

textFieldInsideSearchBar?.textColor = yourcolor

1
ฉันได้แก้ไขคำตอบแล้ว คุณสามารถเข้าถึงฟิลด์ได้โดยใช้ valueforkey ("searchField")
Christian

7
ไม่ใช่ API ส่วนตัว แต่เปราะบางมากและสามารถทำลายการอัปเดต iOS ได้ คุณไม่ควรใช้สิ่งเหล่านี้ในรหัสการผลิต
Lope

2
@Christian - มันไม่สำคัญว่าเมื่อคำตอบเดิมถูกโพสต์ แต่ก็ยังคงอาศัย API ส่วนตัว หากเป็นสาธารณะคุณไม่จำเป็นต้องเข้าถึงsearchFieldผ่าน KVC
Greg Brown

1
โหวตลง ดูคำตอบของ @ juanjo และความคิดเห็นของฉันสำหรับแนวทางที่มีประสิทธิภาพมากขึ้นซึ่งได้รับการอนุมัติจาก Apple และมีโอกาสน้อยที่จะแตกหัก
RobP

1
อย่าใช้คำตอบนี้คุณกำลังเข้าถึง API ส่วนตัวและอาจทำให้แอปของคุณถูกปฏิเสธ
aryaxt

64

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

ใส่คำอธิบายภาพที่นี่


2
จะดีกว่าถ้ามีโค้ดน้อยสำหรับดูองค์ประกอบ ขอบคุณ.
NRR

โซลูชั่นที่สมบูรณ์แบบ!
โมนา

50

การทำงานใน Swift 4 สำหรับฉัน:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.white]

Swift 4.2, IOS 12:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]

ทำงานให้ฉัน
Surjeet Rajput

และเปลี่ยนสีสำหรับทุกแถบค้นหาในโมดูลหรือไม่
Zaporozhchenko Oleksandr

48

หากคุณต้องการทำให้อ่านได้บนพื้นหลังสีเข้มเท่านั้นคุณสามารถเปลี่ยน barStyle ได้ สิ่งต่อไปนี้ทำให้ข้อความและปุ่มในแถบค้นหาเป็นสีขาว:

searchController.searchBar.barStyle = .black

@ เบคอนมันช่วยด้วย! ขอบคุณ
Goppinath

32
public extension UISearchBar {

    public func setTextColor(color: UIColor) {
        let svs = subviews.flatMap { $0.subviews }
        guard let tf = (svs.filter { $0 is UITextField }).first as? UITextField else { return }
        tf.textColor = color
    }
}

ชอบคุณวิธีแก้. ขอบคุณ.
Bagusflyer

คุณยังสามารถเพิ่ม "searchField.backgroundColor" เพื่อควบคุมสีพื้นหลังของช่องข้อความแยกจากสีของแถบ
Sherwin Zadeh

14

สิ่งนี้ใช้ได้กับฉันบน iOS 11, Xcode 9:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.blue

ฉันเขียนไว้AppDelegateแต่ฉันเดาว่ามันใช้ได้ถ้าคุณวางไว้ที่อื่นด้วย


3
นี่เป็นแนวทางที่มีประสิทธิภาพมากกว่าเรื่องไร้สาระของคีย์ - ค่าในคำตอบที่ยอมรับและคำตอบอื่น ๆ อย่างไรก็ตาม Apple ในความชาญฉลาดของพวกเขาได้เลิกใช้ API ที่คุณใช้ที่นี่และเสนอเวอร์ชันใหม่สำหรับ iOS 9.0 ขึ้นไปเช่น[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTextColor:[UIColor blueColor]];นี้แน่นอนว่าเป็น Objective-C พร้อมการแปลที่ชัดเจนเป็น Swift โดยใช้appearance(whenContainedInInstancesOf:)
RobP

2
ดูเหมือนจะไม่ทำงานสำหรับฉันใน Xcode 10, iOS 12 บนอุปกรณ์จริง
Oded

11

ตั้งแต่ Xcode 11 และ iOS 13 จึงสามารถเข้าถึงช่องข้อความได้โดยตรง:

searchBar.searchTextField

คุณสามารถเขียนโค้ดเพื่อให้สามารถเข้าถึงได้เสมอเช่นนี้

extension UISearchBar {
    public var textField: UITextField? {
        if #available(iOS 13.0, *) {
            return searchTextField
        } 

        guard let firstSubview = subviews.first else {
            assertionFailure("Could not find text field")
            return nil
        }

        for view in firstSubview.subviews {
            if let textView = view as? UITextField {
                return textView
            }
        }

        assertionFailure("Could not find text field")

        return nil
    }
}

คุณยังไม่สามารถเลือกได้ด้วยข้อผิดพลาดร้ายแรงรหัสนี้ได้รับการทดสอบตั้งแต่ iOS 7 จนถึง iOS 13GM แต่ฉันจะไปหาเวอร์ชันเสริม

extension UISearchBar {
    public var textField: UITextField {
        if #available(iOS 13.0, *) {
            return searchTextField
        }

        guard let firstSubview = subviews.first else {
            fatalError("Could not find text field")
        }

        for view in firstSubview.subviews {
            if let textView = view as? UITextField {
                return textView
            }
        }

       fatalError("Could not find text field")
    }
}

ในที่สุด! เราสามารถเข้าถึงช่องข้อความได้โดยตรง ขอบคุณ Saren
Mark Moeykens

10

วิธีที่สะดวกที่สุดผมคิดว่าคือการกำหนดคุณสมบัติในtextColorUISearchBar

Swift 3.0

    extension UISearchBar {

       var textColor:UIColor? {
           get {
               if let textField = self.value(forKey: "searchField") as? 
   UITextField  {
                   return textField.textColor
               } else {
                   return nil
               }
           }

           set (newValue) {
               if let textField = self.value(forKey: "searchField") as? 
   UITextField  {
                   textField.textColor = newValue
               }
           }
       }
   }

การใช้งาน

searchBar.textColor = UIColor.blue // Your color

Swift 2.3

extension UISearchBar {

 var textColor:UIColor? {
     get {
         if let textField = self.valueForKey("searchField") as? UITextField  {
             return textField.textColor
         } else {
             return nil
         }
     }

     set (newValue) {
         if let textField = self.valueForKey("searchField") as? UITextField  {
             textField.textColor = newValue
         }
     }
 }
} 

คุณจะใช้เป็น:

searchBar.textColor = UIColor.blueColor() // Your color

ไม่ได้ผลสำหรับฉัน คุณตั้งค่าคุณสมบัติ textcolor เมื่อใด
Kingalione

1
@Kingalione คุณสามารถตั้งค่านี้ได้ใน 'viewDidLoad ()'
Tal Zion

ใช่ฉันต้องการเปลี่ยนสีข้อความตัวยึดตำแหน่ง ตอนนี้ฉันพบวิธีแก้ปัญหาแล้ว ขอบคุณต่อไป
Kingalione

5

ลองสิ่งนี้

searchBar.searchTextField.textColor = .white

ฉันใช้สิ่งนี้กับแอปที่กำหนดเป้าหมายเป็น iOS 11 เป็นต้นไป

[อัปเดต] ฉันสังเกตว่าแอปขัดข้องในเวอร์ชันเก่า (<iOS 13) แต่คอมไพเลอร์ไม่เคยบ่นเกี่ยวกับการตรวจสอบเวอร์ชันโปรดอธิบายสาเหตุที่เกิดขึ้น


คอมไพเลอร์ของฉันบ่น
FrugalResolution

3

คุณสามารถทำได้โดยการเข้าถึง UITextField ภายในแถบค้นหาจากนั้นคุณสามารถเปลี่ยนสีพื้นหลังสีข้อความและคุณสมบัติ UITextField อื่น ๆ ทั้งหมด

เพิ่มส่วนขยายต่อไปนี้เพื่อเข้าถึง textField

extension UISearchBar {
    /// Return text field inside a search bar
    var textField: UITextField? {
        let subViews = subviews.flatMap { $0.subviews }
        guard let textField = (subViews.filter { $0 is UITextField }).first as? UITextField else { return nil
        }
        return textField
    }
}

3

ฉันลองใช้วิธีแก้ปัญหาบางอย่างที่เขียนไว้ข้างต้น แต่ไม่ได้ผล (อีกต่อไปฉันเดา)

หากคุณต้องการจัดการเฉพาะ iOS 13:

mySearchBar.searchTextField.textColor = .red

แต่ถ้าคุณต้องการจัดการ iOS รุ่นเก่าด้วยนี่คือวิธีที่ฉันทำ:

สร้างUISearchBarคลาสแบบกำหนดเองที่เรียกว่าSearchBar : UISearchBar, UISearchBarDelegate นี่SearchBarจะมีUISearchBarDelegateวิธีการที่ฉันต้องการจัดการและdelegateชุดของคลาสนั้น

และฉันเพิ่มในชั้นเรียน:

    var textField: UITextField? {
        if #available(iOS 13.0, *) {
            return self.searchTextField
        }
        return subviews.first?.subviews.first(where: { $0 as? UITextField != nil }) as? UITextField
    }

คำอธิบายสั้น ๆ :

ด้วย iOS13 ตอนนี้คุณสามารถเข้าถึงคำUITextFieldขอบคุณUISearchBar.searchTextFieldซึ่งเป็นประเภทUISearchTextFieldที่สืบทอดมาจากUITextFieldซึ่งสืบทอดมาจาก

เนื่องจากฉันรู้ลำดับชั้นของฉันฉันรู้ว่าฉันtextFieldจะไม่ใช้nillสำหรับเวอร์ชันเก่าดังนั้นในทั้งสองกรณีฉันจึงได้รับฟิลด์ข้อความที่ฉันสามารถปรับแต่งได้อย่างง่ายดายทำงานกับทุกเวอร์ชันตั้งแต่ 9 ถึง 13 วันนี้

นี่คือรหัสทั้งหมดที่จำเป็นเพื่อให้ใช้งานได้:


class SearchBar: UISearchBar, UISearchBarDelegate {

    var textField: UITextField? {
        if #available(iOS 13.0, *) {
            return self.searchTextField
        }
        return subviews.first?.subviews.first(where: { $0 as? UITextField != nil }) as? UITextField
    }


    override func awakeFromNib() {
        super.awakeFromNib()

        delegate = self

        if let textField = textField {
            textField.textColor = .red
            textField.clearButtonMode = .whileEditing
            textField.returnKeyType = .search
        }
    }

}

คุณยังสามารถตั้งค่าการปรับแต่งบางอย่างได้SearchBarโดยเพิ่มสิ่งนี้ใน:

        let searchBar = UISearchBar.appearance(whenContainedInInstancesOf: [SearchBar.self])
        searchBar.backgroundImage = UIImage()
        searchBar.isTranslucent = false
        searchBar.returnKeyType = .search

จากนั้นคุณตั้งค่าเป็น XIB / Storyboard และคุณจัดการกับมันราวกับว่ามันเป็นเรื่องง่ายUISearchBar(ถ้าคุณไม่ลืมผู้ร่วมประชุม!)


2

(โซลูชันนี้ทดสอบสำหรับ Xcode 10 และ iOS 12 เท่านั้น) เพิ่มส่วนขยายเพื่อเข้าถึงช่องข้อความของแถบค้นหา:

extension UISearchBar {
    var textField: UITextField? {
        return subviews.first?.subviews.compactMap { $0 as? UITextField }.first
    }
}

จากนั้นใช้คุณสมบัตินั้นเพื่อกำหนดสีข้อความของช่องข้อความในแถบค้นหาของคุณ:

let searchBar = UISearchBar()
searchBar.textField?.textColor = UIColor.white // or whichever color you want

// แก้ไข

โค้ดด้านบนใช้ไม่ได้กับ iOS 13 วิธีที่ดีกว่าในการจัดการสิ่งนี้คือใช้:

extension UISearchBar {
    var textField: UITextField? {
        return self.subviews(ofType: UITextField.self).first
    }
}

extension UIView {
    var recursiveSubviews: [UIView] {
        return self.subviews + self.subviews.flatMap { $0.recursiveSubviews }
    }

    func subviews<T: UIView>(ofType: T.Type) -> [T] {
        return self.recursiveSubviews.compactMap { $0 as? T }
    }
}

สำหรับ iOS 13 ส่งคืน subviews.first? .subviews.last? .subviews.compactMap {$ 0 เป็น? UITextField} .last
Taras


2

Swift 5.2 และ iOS 13.3.1: -

มันทำงานได้ดี

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]


1

นี่คือแนวทาง "ค้นหา UITextField" เวอร์ชัน Xamarin.iOS C # จะไม่ผิดพลาดหาก UITextField หายไปในลำดับชั้นมุมมองของ iOS ในอนาคต

var tf = searchBar.AllSubViews().FirstOrDefault(v => v is UITextField);
if (tf != null) 
    (tf as UITextField).TextColor = UIColor.White;

public static IEnumerable<UIView> AllSubViews(this UIView view)
{
    foreach (var v in view.Subviews)
    {
        yield return v;
        foreach (var sv in v.AllSubViews())
        {
            yield return sv;
        }
    }
}

0

ในการแก้ปัญหาสถานการณ์ของฉันคือ

id appearance = [UITextField appearanceWhenContainedInInstancesOfClasses:@[UISearchBar.class, BCRSidebarController.class]];
[appearance setTextColor:[UIColor.whiteColor colorWithAlphaComponent:0.56]];

0

Obj-C

UITextField *textField = [self.yourSearchbar valueForKey:@"_searchField"];
textField.textColor = [UIColor redColor];

สวิฟต์ 4.x

let textField = yourSearchbar.value(forKey: "searchField") as? UITextField
textField?.textColor = UIColor.red


0

ใน Swift 5 คุณสามารถทำสิ่งต่างๆดังต่อไปนี้:

yourSearchBar.searchTextField.textColor = .yourColor


-1

Swift 5 Xcode 11.4 iOS 13.4

    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = .white
    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = .systemFont(ofSize: 13)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.