Styling the cancel button in a UISearchBar

前端 未结 21 1370
-上瘾入骨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:58

    Swift 2.1.1:

    There's no simple way to hook in and style the search bar, you need to grab the subview manually from the search bar and then apply your changes.

    var cancelButton: UIButton
    let topView: UIView = self.customSearchController.customSearchBar.subviews[0] as UIView
    for subView in topView.subviews {
     if subView.isKindOfClass(NSClassFromString("UINavigationButton")!) {
        cancelButton = subView as! UIButton
        cancelButton.enabled = true
        cancelButton.setTitle("TestTitle", forState: UIControlState.Normal) // Change to set the title
        cancelButton.setBackgroundImage(UIImage(named: "ImageName"), forState: .Normal) // Change this to set a custom cancel button image, set the title to "" to remove 'Cancel' text
       }
    }
    
    0 讨论(0)
  • 2020-12-02 09:59
    UISearchBar *searchBar;
    [searchBar setShowsCancelButton:YES animated:YES];
    
    UIButton *cancelButton = 
    YES == [searchBar respondsToSelector:NSSelectorFromString(@"cancelButton")] ? 
    [searchBar valueForKeyPath:@"_cancelButton"] : nil;
    
    cancelButton.titleEdgeInsets = UIEdgeInsetsMake(0, -10, 0, 10);
    [cancelButton setTitle:@"New :)" forState:UIControlStateNormal];
    
    0 讨论(0)
  • 2020-12-02 10:02

    After you've initialized your UISearchBar, you can probe into it's subviews and customize each of them. Example:

    for (UIView *view in searchBar.subviews) {
    
        //if subview is the button
        if ([[view.class description] isEqualToString:@"UINavigationButton"]) {
    
            //change the button images and text for different states
            [((UIButton *)view) setEnabled:YES];
            [((UIButton *)view) setTitle:nil forState:UIControlStateNormal];
            [((UIButton *)view) setImage:[UIImage imageNamed:@"button image"] forState:UIControlStateNormal];
            [((UIButton *)view) setBackgroundImage:[UIImage imageNamed:@"button"] forState:UIControlStateNormal];
            [((UIButton *)view) setBackgroundImage:[UIImage imageNamed:@"button_pressed"] forState:UIControlStateSelected];
            [((UIButton *)view) setBackgroundImage:[UIImage imageNamed:@"button_pressed"] forState:UIControlStateHighlighted];
    
        //if the subview is the background
        }else if([[view.class description] isEqualToString:@"UISearchBarBackground"]) {
    
            //put a custom gradient overtop the background
            CAGradientLayer *gradient = [CAGradientLayer layer];
            gradient.frame = view.bounds;
            gradient.colors = [NSArray arrayWithObjects:(id)[[some uicolor] CGColor], (id)[[another uicolor] CGColor], nil];
            [view.layer insertSublayer:gradient atIndex:0];
    
        //if the subview is the textfield
        }else if([[view.class description] isEqualToString:@"UISearchBarTextField"]){
    
            //change the text field if you wish
    
        }
    
    }
    

    Worked out great for me! Especially the gradient :)

    0 讨论(0)
  • 2020-12-02 10:03

    What you want to do is pretty tough. There is no built-in hook to get at the cancel button.

    However, there are a couple of options if you are willing to jimmy open the hood.

    First off, UISearchBar is a UIView, and the Cancel button is also a view, which is added into the search bar as a subview, just as you would expect.

    I have experimented a little, and can tell you that when the button is onscreen it has a size of 48,30.

    So in viewWillAppear, you can do something like this:

    1. Find the cancel button view in [searchBar subviews] by looking for one with size 48,30. (There only seems to be one -- this could change...) You could be doubly careful and look for one that is in approximately the correct position (differs in landscape and portrait).

    2. Add a subview to the cancel button.

    3. The subview should be a UIControl (so that you can set enabled = NO, in order to make sure touch events get to the actual cancel button)

    4. It needs to have the right color and rounded corners; you will need to fudge the size for reasons I don't yet understand (55,30 seems to work)

    5. This will work if searchBar.showsCancelButton is always YES; if you want it to disappear when not editing the search string, you will need to find a hook to add the overlay each time the cancel button appears.

    6. As you can see, this is some ugly tinkering. Do it with eyes wide open.

    0 讨论(0)
  • 2020-12-02 10:03

    If you want to configure your cancel button on UISearchBar you should get the UIButton object from your UISearchBar object. Example below

    UISearchBar *s_bar = [[UISearchBar alloc] initWithFrame:CGRectMake(50,20,300,30)];
    s_bar.delegate = self;
    s_bar.barStyle = UIBarStyleDefault;
    s_bar.showsCancelButton = YES;
    UIButton *cancelButton;
    for (id button in s_bar.subviews)
    {
        if ([button isKindOfClass:[UIButton class]])
        {
            cancelButton=(UIButton*)button;
            break;
        }
    }
    
    0 讨论(0)
  • 2020-12-02 10:04

    Custom UISearchBar and override method -addSubview:

    - (void) addSubview:(UIView *)view {
        [super addSubview:view];
    
        if ([view isKindOfClass:UIButton.class]) {
            UIButton *cancelButton = (UIButton *)view;
            [cancelButton setBackgroundImage:[UIImage imageNamed:@"xxxx.png"] forState:UIControlStateNormal];
            [cancelButton setBackgroundImage:[UIImage imageNamed:@"yyyy.png"] forState:UIControlStateHighlighted];
        }
    }
    
    0 讨论(0)
提交回复
热议问题