Styling the cancel button in a UISearchBar

前端 未结 21 1375
-上瘾入骨i
-上瘾入骨i 2020-12-02 09:13

I have a UISearchBar that has a cancel button (it\'s displayed using -(void)setShowsCancelButton:animated). I\'ve changed the tintColor of the sear

21条回答
  •  情深已故
    2020-12-02 09:54

    I'll give a detailed answered regarding the UIAppearance technique. First, you need to understand that the cancel button is a private UINavigationButton:UIButton. After some inspection, it appears that UINavigationButton will respond to those UIAppearance selectors:

    // inherited from UINavigationButton
    @selector(setTintColor:)
    @selector(setBackgroundImage:forState:style:barMetrics:)
    @selector(setBackgroundImage:forState:barMetrics:)
    @selector(setTitleTextAttributes:forState:)
    @selector(setBackgroundVerticalPositionAdjustment:forBarMetrics:)
    @selector(setTitlePositionAdjustment:forBarMetrics:)
    @selector(setBackButtonBackgroundImage:forState:barMetrics:)
    @selector(setBackButtonTitlePositionAdjustment:forBarMetrics:)
    @selector(setBackButtonBackgroundVerticalPositionAdjustment:forBarMetrics:)
    
    // inherited from UIButton
    @selector(setTitle:forState:)
    

    Coincidentally, those selectors match those of a UIBarButtonItem. Meaning the trick is to use two separate UIAppearance to handle the private class UINavigationButton.

    /* dual appearance technique by Cœur to customize a UINavigationButton */
    Class barClass = [UISearchBar self];
    
    UIBarButtonItem *barButtonItemAppearanceInBar = [UIBarButtonItem appearanceWhenContainedIn:barClass, nil];
    [barButtonItemAppearanceInBar setTintColor:...];
    [barButtonItemAppearanceInBar setBackgroundImage:... forState:... style:... barMetrics:...];
    [barButtonItemAppearanceInBar setBackgroundImage:... forState:... barMetrics:...];
    [barButtonItemAppearanceInBar setTitleTextAttributes:... forState:...];
    [barButtonItemAppearanceInBar setBackgroundVerticalPositionAdjustment:... forBarMetrics:...];
    [barButtonItemAppearanceInBar setTitlePositionAdjustment:... forBarMetrics:...];
    // only for a backButton in an UINavigationBar, not for a cancelButton in an UISearchBar
    //[barButtonItemAppearanceInBar setBackButtonBackgroundImage:... forState:... barMetrics:...];
    //[barButtonItemAppearanceInBar setBackButtonTitlePositionAdjustment:... forBarMetrics:...];
    //[barButtonItemAppearanceInBar setBackButtonBackgroundVerticalPositionAdjustment:... forBarMetrics:...];
    
    UIButton *buttonAppearanceInBar = [UIButton appearanceWhenContainedIn:barClass, nil];
    // warning: doesn't work for iOS7+
    [buttonAppearanceInBar setTitle:... forState:...];
    

    This will let you customize your Cancel button as much as you want.

提交回复
热议问题