【问题标题】:How to change the corner radius of UISegmentedControl?如何更改 UISegmentedControl 的圆角半径?
【发布时间】:2014-06-12 14:46:37
【问题描述】:

是否可以更改 UISegmentedControl 的圆角半径?我尝试了以下方法来更改 UIView 的角半径。

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

这不起作用,因为您可以看到它只切断了 UISegmentedControl 的角:

【问题讨论】:

    标签: ios cocoa-touch uiview uikit uisegmentedcontrol


    【解决方案1】:

    这应该可行:

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

    设置cornerRadius后需要指定边框。

    【讨论】:

    • 只有你想增加cornerRadius才有效
    • 它不能解决最初的问题,只有角落被切掉。请参阅下面的答案。
    • 对于 Swift:self.layer.cornerRadius = 15.0; self.layer.borderColor = UIColor.white.cgColor; self.layer.borderWidth = 1.0; self.layer.masksToBounds = true;
    • @Manish 如何添加 UISegmentedControl?我在 iOS 13 中试过,效果很好。
    • @user2185354 你能上传一个演示吗?
    【解决方案2】:

    在 UIView 中嵌入 UISegmentedControl 并为 UIView 设置圆角半径。

    Objective-C

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

    斯威夫特

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

    【讨论】:

    • 别忘了在 storyboard 的 UIView 中添加 Clip 子视图
    • @Ilario 请解释一下
    【解决方案3】:

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

    我决定再试一次,我终于让它完美地工作了!! 一行代码解决了这一切!查看代码

    代码

    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)
        }
    }
    

    这个想法是,Apple 使用一个 UIImageView,它有自己的方形图像和所选移动段的色调。我们想要做的是覆盖它的图像,这样我们就可以控制颜色、圆角半径等。之后,我们想要删除 Apple 的 3 个默认动画之一(有问题的那个使片段在触摸时放大 - - 我使用foregroundImageView.layer.animationKeys() 找出影响移动段的动画)

    【讨论】:

    • 圆形矩形正在工作。但是你是如何改变所选索引的背景颜色的。在我的情况下,设置为活动和非活动情况。
    • 如果我没记错的话,是foregroundImageView.backgroundColor = UIColor.darkGray
    • 嗨@RaimondoPrevidi 你有什么解决方案来解决这个变化的框架吗?
    • 很遗憾没有。我只是使用了苹果给我们的东西,牺牲了圆角。对我来说,花更多时间尝试破解苹果的代码是不值得的。
    • 不,我暂时放下这个。我很快将项目升级到 iOS 14,所以我会再试一次,看看现在是否可行
    【解决方案4】:

    分段控件不会改变它绘制角的方式,因此它会继续以自己的方式绘制角,然后您将它们切断。您不负责分段控件如何绘制其边界形状。如果您真的不喜欢它的绘制方式,则必须从头开始设计自己的替代控件。您可以合法地尝试做的最接近的事情是设置分段控件的背景图像。

    【讨论】:

    • 我会传给设计师的:)
    【解决方案5】:

    您可以通过增加图层的 cornerRadius 来更改 UISegmentedControlcornerRadius,或者从 iOS 13 及更高版本 将图层设置为ma​​skedCorner 属性。

    此示例删除默认的 cornerRadius 并拉直 backgroundImage

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

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

    【讨论】:

    • 谢谢,但这不会影响“移动”部分的圆角半径,只会影响背景部分:( 编辑:我终于找到了一种使用@访问层次结构中“移动”视图的方法987654323@ (基本上是段的背景,然后是移动的,然后是前景(即每个段的标题),所以“移动”视图总是在中间)。然后我将 Image 和 highlightImage 设置为空 UIImage( ),将 imageView 的边界插入 5,并将 backgroundColor 设置为所需的颜色。
    • 它看起来和它应该的完全一样,问题是在点击动画期间视图增长到segmentedControl一样大,然后再次缩小,所以看起来不对。请注意,我在 segmentedControl 的layoutSubviews() 中进行这些更改。看看我下面的答案,看看我目前的结果。
    • @RaimondoPrevidi 如果您为选定状态设置自定义背景图像,它在移动时是否仍在改变其角半径?
    • 问题是我想要标题,而不是图像。并且在文档上说你只能拥有一个或另一个。
    【解决方案6】:

    针对 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
    

    【讨论】:

      【解决方案7】:

      iOS13 有一些变化。因此,您必须在layoutSubviews 内设置borderRadius:

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

      【讨论】:

      • 嘿,你知道如何改变 selectedSegment 视图的圆角半径吗?
      • 我不知道。我也不会推荐它。通过适当的工程时间,您可以创建任何布局,但值得花时间吗?我会将 UX 设计者倾向于 Apple 内置的 UX,并避免微定制
      • 这是金子,谢谢分享。注意:您也可以移至 layoutSubviews 其他设置器,以正确应用它们。我自己需要borderWidth。
      • @RaimondoPrevidi 通过将 CALayer 设置为它的 maskedCorners 属性 stackoverflow.com/a/60651341/5324541,检查我在 iOS 13 及更高版本中编辑角半径的答案
      • 简单!非常感谢。
      【解决方案8】:

      您的结果是因为其他东西(自定义绘图?)控制边框而不是图层。幸运的是,图层设置似乎具有优先权。

      如果你知道你需要什么边框颜色,你可以添加(示例):

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

      【讨论】:

      • 如何改变圆角半径?
      • 这不会改变拐角半径。它只是补充了问题中发布的原始代码以获得预期的结果。
      【解决方案9】:

      以前的解决方案对我没有用。我的解决方案是:

      要将UISegmentedControl 嵌入超级视图中,然后将-1 分配给约束前导、尾随、底部、顶部,以切断UISegmentedControl 边界。 最后superview应该这样配置:

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

      【讨论】:

        【解决方案10】:

        这是 Yakiv's postSwift 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
        

        【讨论】:

          【解决方案11】:

          使用以下代码:

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

          【讨论】:

          • 这通常会起作用。提供您的代码,以便我查看!
          • 检查角半径的一些值-segmentContrl.layer.cornerRadius = 3.0;
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-07
          • 1970-01-01
          • 2016-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多