Remove UISegmentedControl separators completely. (iphone)

前端 未结 9 1676
Happy的楠姐
Happy的楠姐 2020-12-05 05:30

Is there a way to completely remove the line separating the two segments in a UISegmentedControl?

Setting the segmentedControlStyle is not helping.

相关标签:
9条回答
  • 2020-12-05 05:33

    If anybody wants this kind of UISegmentedControl View-

    EDITED:- Swift 3.0 extensions

        extension UISegmentedControl {
    
        func customizeAppearance(for height: Int) {
    
            setTitleTextAttributes([NSFontAttributeName:UIFont(name:"Helvetica Neue", size:13.0)!,NSForegroundColorAttributeName:UIColor.white], for:.normal)
            setTitleTextAttributes([NSFontAttributeName:UIFont(name:"Helvetica Neue", size:13.0)!,NSForegroundColorAttributeName:UIColor.white], for:.selected)
            setDividerImage(UIImage().colored(with: .clear, size: CGSize(width: 1, height: height)), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
            setBackgroundImage(UIImage().colored(with: .clear, size: CGSize(width: 1, height: height)), for: .normal, barMetrics: .default)
            setBackgroundImage(UIImage().colored(with: UIColor.init(red: 215/255.0, green: 0.0, blue: 30/255.0, alpha: 1.0), size: CGSize(width: 1, height: height)), for: .selected, barMetrics: .default);
    
            for  borderview in subviews {
                let upperBorder: CALayer = CALayer()
                upperBorder.backgroundColor = UIColor.init(red: 215/255.0, green: 0.0, blue: 30/255.0, alpha: 1.0).cgColor
                upperBorder.frame = CGRect(x: 0, y: borderview.frame.size.height-1, width: borderview.frame.size.width, height: 1)
                borderview.layer.addSublayer(upperBorder)
            }
    
        }
    }
    
    extension UIImage {
    
        func colored(with color: UIColor, size: CGSize) -> UIImage {
            UIGraphicsBeginImageContext(size)
            let context = UIGraphicsGetCurrentContext()
            context!.setFillColor(color.cgColor);
            let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: size)
            context!.fill(rect);
            let image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            return image!
        }
    }
    

    The UIImage extension generates a colored image with desired size.

    Forcing the height parameter in customizeAppearance avoid any crash when building the context.

    You can make it even more reusable by extracting each customization attribute and put it as function's parameters ;)

    Here is sample code, tested over iOS 9 and works fine for me.

    Add these lines of code in viewDidLoad-

    [yourSegmentControl setTitleTextAttributes:@{ NSFontAttributeName:[UIFont fontWithName:@"Roboto-black" size:13.0],NSForegroundColorAttributeName:[UIColor whiteColor] }forState:UIControlStateSelected];
    
    [yourSegmentControl setTitleTextAttributes:@{ NSFontAttributeName:[UIFont fontWithName:@"Roboto-black" size:13.0],NSForegroundColorAttributeName:[UIColor whiteColor] }forState:UIControlStateNormal];
    
    [yourSegmentControl setDividerImage:[self imageWithColor:[UIColor clearColor]] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    
    [yourSegmentControl setBackgroundImage:[self imageWithColor:[UIColor clearColor]] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    
    [yourSegmentControl setBackgroundImage:[self imageWithColor:[UIColor colorWithRed:215/255.0 green:0 blue:30/255.0 alpha:1.0]] forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
    
    for (UIView *borderview in yourSegmentControl.subviews) {
    
        CALayer *upperBorder = [CALayer layer];
    
        upperBorder.backgroundColor = [UIColor colorWithRed:215/255.0 green:0 blue:30/255.0 alpha:1.0].CGColor;
    
        upperBorder.frame = CGRectMake(0, borderview.frame.size.height-1, borderview.frame.size.width, 1.0f);
    
        [borderview.layer addSublayer:upperBorder];
    }
    

    and

    - (UIImage *)imageWithColor:(UIColor *)color {
        CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        CGContextSetFillColorWithColor(context, [color CGColor]);
        CGContextFillRect(context, rect);
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return image;
    }
    

    Here is the Swift extension for achieving same view in Swift-

    yourSegmentControl.setTitleTextAttributes([NSFontAttributeName:UIFont(name:"Helvetica Neue", size:13.0)!,NSForegroundColorAttributeName:UIColor.whiteColor()], forState:UIControlState.Normal)
    
    yourSegmentControl.setTitleTextAttributes([NSFontAttributeName:UIFont(name:"Helvetica Neue", size:13.0)!,NSForegroundColorAttributeName:UIColor.whiteColor()], forState:UIControlState.Selected)
    
    yourSegmentControl.setDividerImage(self.imageWithColor(UIColor.clearColor()), forLeftSegmentState: UIControlState.Normal, rightSegmentState: UIControlState.Normal, barMetrics: UIBarMetrics.Default)
    
    yourSegmentControl.setBackgroundImage(self.imageWithColor(UIColor.clearColor()), forState:UIControlState.Normal, barMetrics:UIBarMetrics.Default)
    
    yourSegmentControl.setBackgroundImage(self.imageWithColor(UIColor.init(red: 215/255.0, green: 0.0, blue: 30/255.0, alpha:1.0)), forState:UIControlState.Selected, barMetrics:UIBarMetrics.Default);
    
    for  borderview in yourSegmentControl.subviews {
    
    let upperBorder: CALayer = CALayer()
    upperBorder.backgroundColor = UIColor.init(red: 215/255.0, green: 0.0, blue: 30/255.0, alpha: 1.0).CGColor
    upperBorder.frame = CGRectMake(0, borderview.frame.size.height-1, borderview.frame.size.width, 1.0);
    borderview.layer .addSublayer(upperBorder);
    
    }
    

    and

    func imageWithColor(color: UIColor) -> UIImage {
    
        let rect = CGRectMake(0.0, 0.0, 1.0, yourSegmentControl.frame.size.height)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        CGContextSetFillColorWithColor(context, color.CGColor);
        CGContextFillRect(context, rect);
        let image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image
    
    }
    
    0 讨论(0)
  • 2020-12-05 05:37

    @naveed's and @Jon Setting's answers saved my day!

    But as a bit of a perfectionist, i was frustrated to find out that this code also leaves holes in the outer border of the control:

    So I added a few lines of code to get rid of those and make it look neat:

    The complete code for this would be

    CGFloat h = self.segControlOut.frame.size.height;
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, h), NO, 0.0);
    
    // draw the missing dots with the control border color
    [self.segControlOut.tintColor set];
    UIRectFrame( CGRectMake(0, -1, 1, 2.5) );
    UIRectFrame( CGRectMake(0, h-1.5, 1, 2.5) );
    
    UIImage *blank = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [self.segControlOut setDividerImage:blank
                    forLeftSegmentState:UIControlStateNormal
                      rightSegmentState:UIControlStateNormal
                             barMetrics:UIBarMetricsDefault];
    
    0 讨论(0)
  • 2020-12-05 05:38

    No, there is not. You should look into creating the UISegmentedControl functionality manually. Maybe use two UIButtons.

    0 讨论(0)
  • 2020-12-05 05:40

    Use this method to change your segment divider image:

    [segmentControl setDividerImage:dividerimg
                forLeftSegmentState:UIControlStateNormal
                  rightSegmentState:UIControlStateNormal
                         barMetrics:UIBarMetricsDefault];
    
    0 讨论(0)
  • 2020-12-05 05:40

    You can remove all background, border and separators from a UISegmentedControl by setting a black image. Or you can set custom colours.

    The below example removes all borders/seperators, and sets the background to be white with 0.2 alpha, and the selected segment to be white with alpha 1.0

    [self.segmentedControl setBackgroundImage:[self imageWithColor:[UIColor colorWithWhite:1.0 alpha:0.2]] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    [self.segmentedControl setBackgroundImage:[self imageWithColor:[UIColor colorWithWhite:1.0 alpha:1.0]] forState:UIControlStateSelected  barMetrics:UIBarMetricsDefault];
    
    - (UIImage *)imageWithColor:(UIColor *)color {
        CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        CGContextSetFillColorWithColor(context, [color CGColor]);
        CGContextFillRect(context, rect);
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return image;
    }
    
    0 讨论(0)
  • 2020-12-05 05:48

    I combined the previous answers into a Swift extension.

    I wanted to remove all borders and dividers. This code just uses the normal segment colors, e.g. tint and background for selected / deselected.

    Call

    segmentedControl.removeBorders()
    

    Here's the extension

    extension UISegmentedControl {
        func removeBorders() {
            setBackgroundImage(imageWithColor(backgroundColor!), forState: .Normal, barMetrics: .Default)
            setBackgroundImage(imageWithColor(tintColor!), forState: .Selected, barMetrics: .Default)
            setDividerImage(imageWithColor(UIColor.clearColor()), forLeftSegmentState: .Normal, rightSegmentState: .Normal, barMetrics: .Default)
        }
    
        // create a 1x1 image with this color
        private func imageWithColor(color: UIColor) -> UIImage {
            let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
            UIGraphicsBeginImageContext(rect.size)
            let context = UIGraphicsGetCurrentContext()
            CGContextSetFillColorWithColor(context, color.CGColor);
            CGContextFillRect(context, rect);
            let image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            return image
        }
    }
    
    0 讨论(0)
提交回复
热议问题