How to adjust UIToolBar left and right padding

后端 未结 10 508
自闭症患者
自闭症患者 2020-12-02 05:05

I create one UIToolbar with code and another with interface builder. But, found out the two toolbar having different left and right padding which shown below:

From I

相关标签:
10条回答
  • 2020-12-02 05:44

    This is a great question and even with the solutions provided - it did not resolve the problem on iOS11.

    WORKING SOLUTION

    If you create a new extension of UIButton:

    class BarButton: UIButton {
    
        override var alignmentRectInsets: UIEdgeInsets {
            return UIEdgeInsetsMake(0, 16, 0, 16)
        }
    
    }
    

    Then when you use it in your layout:

    lazy var btnLogin: BarButton = {
        let btn = BarButton(type: .custom)
        // Add your button settings
    
        btn.widthAnchor.constraint(equalToConstant: self.frame.size.width).isActive = true
        btn.heightAnchor.constraint(equalToConstant: 50).isActive = true
        btn.translatesAutoresizingMaskIntoConstraints = false
        return btn
    }()
    

    This solved a very annoying problem, if you have any issues give me a shout.

    0 讨论(0)
  • 2020-12-02 05:44

    You can change offset and width of your toolbar, if you want to use customview (initWithCustomView)

    [myToolBar setFrame:CGRectMake(-10, 0, [UIScreen mainScreen].bounds.size.width+10, 44)];
    
    0 讨论(0)
  • 2020-12-02 05:50

    Finally for having customized background image for the UIBarButtonItem and to accomodate the alignment, I have abandon UIBarButtonItem and adding UIButton manually.

    UIImage *buttonImage = [[UIImage imageNamed:@"button.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0];
    UIButton *btnTest = [UIButton buttonWithType:UIButtonTypeCustom];
    [btnTest setBackgroundImage:buttonImage forState:UIControlStateNormal];
    [btnTest setTitle:@"Back" forState:UIControlStateNormal];   
    [btnTest.titleLabel setFont:[UIFont boldSystemFontOfSize:13]];  
    [btnTest setBackgroundImage:[imgToolbarButton stretchableImageWithLeftCapWidth:5 topCapHeight:0]  forState:UIControlStateNormal];
    [btnTest addTarget:self action:@selector(clearDateEdit:) forControlEvents:UIControlEventTouchUpInside];
    btnTest.frame = CGRectMake(0.0, 0.0, 50, 30);
    [self.toolbar addSubview:btnTest];
    [btnTestItem release];
    
    0 讨论(0)
  • 2020-12-02 05:51

    Before iOS 11

    You had three possible solutions:

    • The first was using fixed a space item UIBarButtonItem(barButtonSystemItem: .fixedSpace …) with a negative width
    • The other was to override alignmentRectInsets on the custom view
    • The last one, if you use UIButton as your item's custom view, you can override contentEdgeInsets and hitTest(_:with:)

    Absolutely, the first solution seems better than other

    UIBarButtonItem *negativeSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    negativeSeparator.width = -12;
    

    if you use swift, code will be look like this

    var negativeSeparator = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
    negativeSeparator.width = -12
    

    After iOS 11(contain iOS 11)

    unfortunately, all the solution can't be use in iOS 11

    • first solution: setting a negative width no longer works
    • second solution: override alignmentRectInsets will cause part of item no longer receives touches
    • the last solution: i think override hitTest(_:with:) is not a good idea, don't do this please!

    You can also see some suggestion on the Developer Forums, but after you look all the comment, you will find suggestion on this topic is to create a custom UINavigationBar subclass and do something complexity.

    Oh my god, All i want to do is to change the padding, not the navigation bar!

    Fortunately, we can do this with a trick in iOS 11!

    Here We Go:

    1. create a custom button

    • set translatesAutoresizingMaskIntoConstraints as false
    • override alignmentRectInsets
      • item in right side use UIEdgeInsets(top: 0, left: -8, bottom: 0, right: 8)
      • item in left side use UIEdgeInsets(top: 0, left: 8, bottom: 0, right: -8)

        if you don't know alignmentRectInsets, you can read this blog first

    swift version

    var customButton = UIButton(type: .custom)
    customButton.overrideAlignmentRectInsets = UIEdgeInsets(top: 0, left: x, bottom: 0, right: -x) // you should do this in your own custom class
    customButton.translatesAutoresizingMaskIntoConstraints = false;
    

    objective-c version

    UIButton *customButton = [UIButton buttonWithType:UIButtonTypeCustom];
    customButton.overrideAlignmentRectInsets = UIEdgeInsetsMake(0, x, 0, -x); // you should do this in your own custom class
    customButton.translatesAutoresizingMaskIntoConstraints = NO;
    

    2. create an item with your custom button

    swift version

    var item = UIBarButtonItem(customView: customButton)
    

    objective-c version

    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:customButton]
    

    3. create a fixedSpace type UIBarButtonItem with positive width

    set a positive value, not a negative value

    swift version

    var positiveSeparator = UIBarButtonItem(barButtonSystemItem:.fixedSpace, target: nil, action: nil)
    positiveSeparator.width = 8
    

    objective-c version

    UIBarButtonItem *positiveSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    positiveSeparator.width = 8;
    

    4. set an array to leftitems or rightitems

    fixedSpace type UIBarButton item must be the first element in array.

    swift version

    self.navigationItem.leftBarButtonItems = [positiveSeparator, item, ...]
    

    objective-c version

    self.navigationItem.leftBarButtonItems = @{positiveSeparator, item, ...}
    

    Well Done

    after you doing all of the steps, you will see your padding become smaller and type area seems correct!

    If you find something wrong, please let me know! I will try my best to answer your question!

    Note

    Before iOS 11, you should care about the device's screen width; if the screen is 5.5 inch, the negative is -12 pt, on other screens is -8pt.

    If you use my solution on iOS 11, you don't need to care about the device screen, just set 8pt, You should care about item's position in navigation bar, left side or right side, this will affect your custom view's alignmentRectInsets

    Want more tap area

    If you want to promise your tap area is larger than 44 * 44 , you can override method below

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
        CGSize acturalSize = self.frame.size;
        CGSize minimumSize = kBarButtonMinimumTapAreaSize;
        CGFloat verticalMargin = acturalSize.height - minimumSize.height >= 0 ? 0 : ((minimumSize.height - acturalSize.height ) / 2);
        CGFloat horizontalMargin = acturalSize.width - minimumSize.width >= 0 ? 0 : ((minimumSize.width - acturalSize.width ) / 2);
        CGRect newArea = CGRectMake(self.bounds.origin.x - horizontalMargin, self.bounds.origin.y - verticalMargin, self.bounds.size.width + 2 * horizontalMargin, self.bounds.size.height + 2 * verticalMargin);
        return CGRectContainsPoint(newArea, point);
    }
    
    0 讨论(0)
提交回复
热议问题