简体   繁体   English

如何更改 UISegmentedControl 的圆角半径?

[英]How to change the corner radius of UISegmentedControl?

Is it possible to change the corner radius of UISegmentedControl?是否可以更改 UISegmentedControl 的角半径? I have tried the following approach which we use to change a UIView's corner radius.我尝试了以下方法来更改 UIView 的角半径。

    self.segmentedControl.layer.cornerRadius = 15.0;
    self.segmentedControl.layer.masksToBounds = YES;

This did not work as you can see it only cuts off the UISegmentedControl's corner.这不起作用,因为您可以看到它只切断了 UISegmentedControl 的角落。在此处输入图片说明

Thanks!谢谢!

This should work:这应该有效:

self.segmentedControl.layer.cornerRadius = 15.0;
self.segmentedControl.layer.borderColor = [UIColor whiteColor].CGColor;
self.segmentedControl.layer.borderWidth = 1.0f;
self.segmentedControl.layer.masksToBounds = YES;

You need to specify the border after setting cornerRadius.设置cornerRadius后需要指定边框。

Embed UISegmentedControl inside UIView and set corner radius for UIView .在 UIView 中嵌入 UISegmentedControl 并为UIView设置圆角半径。

Objective-C目标-C

outerView.layer.cornerRadius = CGRectGetHeight(outerView.bounds) / 2;
outerView.layer.borderColor = [UIColor blueColor].CGColor;
outerView.layer.borderWidth = 1;

Swift迅速

outerView.layer.cornerRadius = CGRectGetHeight(outerView.bounds) / 2
outerView.layer.borderColor = UIColor.blueColor().CGColor
outerView.layer.borderWidth = 1

转角的 UISegmentedControl

iOS 13 / 14 - FINALLY WORKING!!! iOS 13 / 14 - 终于可以使用了!!!

图像替代

I decided to give it another go, and I finally got it working perfectly!!我决定再试一次,我终于让它完美地工作了!! There's one line of code that fixed it all!有一行代码可以解决所有问题! Check out the code查看代码

Code :代码

class CustomSegmentedControl: UISegmentedControl{
    private let segmentInset: CGFloat = 5       //your inset amount
    private let segmentImage: UIImage? = UIImage(color: UIColor.red)    //your color

    override func layoutSubviews(){
        super.layoutSubviews()

        //background
        layer.cornerRadius = bounds.height/2
        //foreground
        let foregroundIndex = numberOfSegments
        if subviews.indices.contains(foregroundIndex), let foregroundImageView = subviews[foregroundIndex] as? UIImageView
        {
            foregroundImageView.bounds = foregroundImageView.bounds.insetBy(dx: segmentInset, dy: segmentInset)
            foregroundImageView.image = segmentImage    //substitute with our own colored image
            foregroundImageView.layer.removeAnimation(forKey: "SelectionBounds")    //this removes the weird scaling animation!
            foregroundImageView.layer.masksToBounds = true
            foregroundImageView.layer.cornerRadius = foregroundImageView.bounds.height/2
        }
    }
}

extension UIImage{
    
    //creates a UIImage given a UIColor
    public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
        let rect = CGRect(origin: .zero, size: size)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        color.setFill()
        UIRectFill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    
        guard let cgImage = image?.cgImage else { return nil }
        self.init(cgImage: cgImage)
    }
}

The idea is that Apple uses a UIImageView with its own square image and tint for the selected moving segment.这个想法是 Apple 使用 UIImageView 和它自己的方形图像和所选移动段的色调。 What we want to do is instead overwrite its image so we have control on the color, corner radius, etc. After that, we want to remove one of Apple's 3 default animations (the one that was problematic made the segment scale up on touch -- I used foregroundImageView.layer.animationKeys() to find out what animations were affecting the moving segment)我们想要做的是覆盖它的图像,这样我们就可以控制颜色、圆角半径等。在那之后,我们想要删除 Apple 的 3 个默认动画之一(有问题的一个使片段在触摸时放大- - 我使用了foregroundImageView.layer.animationKeys()来找出影响移动片段的动画)

The segmented control is not going to change the way it draws its corners, so it is continuing to draw its corners in its own way and you are then cutting them off.分段控件不会改变它绘制角的方式,因此它会继续以自己的方式绘制角,然后您将它们切断。 You are not in charge of how a segmented control draws its boundary shape.您不负责分段控件如何绘制其边界形状。 If you truly don't like the way it's drawn, you'll have to devise your own substitute control from scratch.如果您真的不喜欢它的绘制方式,则必须从头开始设计自己的替代控件。 The closest you can legitimately come to the kind of thing you're trying to do is to set the segmented control's background image.您可以合法地尝试做的最接近的事情是设置分段控件的背景图像。

You're able to change the UISegmentedControl cornerRadius by increasing the layer its cornerRadius or from iOS 13 and above by setting the layer its maskedCorner property.您可以通过增加图层的cornerRadius或从iOS 13 及更高版本通过设置图层的maskedCorner属性来更改UISegmentedControlcornerRadius

This example removes the default cornerRadius and straightens the backgroundImage :此示例删除默认的cornerRadius并拉直backgroundImage

if #available(iOS 13.0, *) {
    segmentedControl.layer.maskedCorners = .init()
} else {
    segmentedControl.layer.cornerRadius = 0
}

Source: https://developer.apple.com/documentation/quartzcore/calayer/2877488-maskedcorners来源: https : //developer.apple.com/documentation/quartzcore/calayer/2877488-maskedcorners

Updated for Swift 3 & Xcode 8.2 compatibility针对 Swift 3 和 Xcode 8.2 兼容性进行了更新

    mySegmentedControl.layer.cornerRadius = 25.0
    mySegmentedControl.layer.borderColor = UIColor.white.cgColor
    mySegmentedControl.layer.borderWidth = 1.0
    mySegmentedControl.layer.masksToBounds = true

Your result is because something other (custom drawing?) controls the border and not the layer.您的结果是因为其他(自定义绘图?)控制边框而不是图层。 Luckily it seems that that layer settings have priority.幸运的是,该图层设置似乎具有优先权。

If you know what border color you need, you can just add (example):如果你知道你需要什么边框颜色,你可以添加(示例):

self.segmentedControl.layer.borderColor = [UIColor whiteColor].CGColor;
self.segmentedControl.layer.borderWidth = 1.0;

The previous solutions never worked for me.以前的解决方案对我不起作用。 My solution is:我的解决办法是:

To embed the UISegmentedControl inside a superview, then assign -1 to the constraints leading, trailing, bottom, top, in order to cut off the UISegmentedControl border.要将UISegmentedControl嵌入到UISegmentedControl视图中,然后将 -1 分配给约束前导、尾随、底部、顶部,以切断UISegmentedControl边框。 Finally the superview should be configured in this way:最后超级视图应该这样配置:

segmentedControl.superview.clipsToBounds = true
segmentedControl.superview.layer.cornerRadius = 0 //whatever
segmentedControl.superview.layer.borderWidth = 1
segmentedControl.superview.layer.borderColor = segmentedControl.tintColor.CGColor

There are some changes in iOS13. iOS13 有一些变化。 Hence you must set the borderRadius from within layoutSubviews :因此,您必须从layoutSubviews设置 borderRadius :

override func layoutSubviews() {
    super.layoutSubviews()
    layer.cornerRadius = 2
}

This is a converted and working code for Swift 4.1 and Xcode 9.3 of Yakiv's post .这是Yakiv 帖子的Swift 4.1 和 Xcode 9.3的转换和工作代码。

segmentedOuterView.layer.cornerRadius = segmentedOuterView.bounds.height / 2
segmentedOuterView.layer.borderColor = UIColor.red.cgColor
segmentedOuterView.layer.borderWidth = 1
segmentedOuterView.layer.masksToBounds = true

Use the following code :使用以下代码:

segmentContrl.layer.borderColor=*anycolor*.CGColor;
segmentContrl.layer.cornerRadius = 0.0;
segmentContrl.layer.borderWidth = 1.5f;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM