如何在 UISegmentedControl 中仅显示所选项目的底部边框? [英] How to display only bottom border for selected item in UISegmentedControl?

查看:18
本文介绍了如何在 UISegmentedControl 中仅显示所选项目的底部边框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 iOS 开发非常陌生,在为课程构建应用程序时遇到了一些问题.

I'm extremely new to iOS development and ran into some trouble while building an app for a course.

我创建了一个分段控件,它的 init 函数(如下所示)在包含分段控件的视图控制器类中被调用.我能够从分段控件类中删除分段控件的所有边框和分隔线,如下所示:

I created a segmented control and its init function (shown below) is being called in the view controller class containing the segmented control. I was able to remove all borders and dividers of the segmented control from the segmented control class as follows:

import Foundation
import UIKit

class CashSegmentedControl: UISegmentedControl{

func initUI(){
    removeBorders()
}

func removeBorders(){
    self.tintColor = UIColor.clear

}

我希望它在每个片段被选中时在每个片段下都有一条线(类似于 instagram)

I want it to have a line under each segment WHEN the segment is selected (similar to instagram)

我搜索了很多,并在 StackOverflow 上找到了一些帖子,但它们似乎适用于旧版本的 Swift.我真的很感激这方面的任何帮助,如果有更好的自定义边框解决方案(除了我所做的),我很想了解更多!

I've searched a lot and come across some posts on StackOverflow but they seem to be for older versions of Swift. I'd really appreciate any help in this matter, and if there is a better solution for customising the borders (other than what I have done), I'd love to learn more!

非常感谢:)

推荐答案

在单独的 swift 文件中添加以下代码(command+N -> New File):

Add the following code in a separate swift file (command+N -> New File):

extension UISegmentedControl{
    func removeBorder(){
        let backgroundImage = UIImage.getColoredRectImageWith(color: UIColor.white.cgColor, andSize: self.bounds.size)
        self.setBackgroundImage(backgroundImage, for: .normal, barMetrics: .default)
        self.setBackgroundImage(backgroundImage, for: .selected, barMetrics: .default)
        self.setBackgroundImage(backgroundImage, for: .highlighted, barMetrics: .default)

        let deviderImage = UIImage.getColoredRectImageWith(color: UIColor.white.cgColor, andSize: CGSize(width: 1.0, height: self.bounds.size.height))
        self.setDividerImage(deviderImage, forLeftSegmentState: .selected, rightSegmentState: .normal, barMetrics: .default)
        self.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.gray], for: .normal)
        self.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor(red: 67/255, green: 129/255, blue: 244/255, alpha: 1.0)], for: .selected)
    }

    func addUnderlineForSelectedSegment(){
        removeBorder()
        let underlineWidth: CGFloat = self.bounds.size.width / CGFloat(self.numberOfSegments)
        let underlineHeight: CGFloat = 2.0
        let underlineXPosition = CGFloat(selectedSegmentIndex * Int(underlineWidth))
        let underLineYPosition = self.bounds.size.height - 1.0
        let underlineFrame = CGRect(x: underlineXPosition, y: underLineYPosition, width: underlineWidth, height: underlineHeight)
        let underline = UIView(frame: underlineFrame)
        underline.backgroundColor = UIColor(red: 67/255, green: 129/255, blue: 244/255, alpha: 1.0)
        underline.tag = 1
        self.addSubview(underline)
    }

    func changeUnderlinePosition(){
        guard let underline = self.viewWithTag(1) else {return}
        let underlineFinalXPosition = (self.bounds.width / CGFloat(self.numberOfSegments)) * CGFloat(selectedSegmentIndex)
        UIView.animate(withDuration: 0.1, animations: {
            underline.frame.origin.x = underlineFinalXPosition
        })
    }
}

extension UIImage{

    class func getColoredRectImageWith(color: CGColor, andSize size: CGSize) -> UIImage{
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        let graphicsContext = UIGraphicsGetCurrentContext()
        graphicsContext?.setFillColor(color)
        let rectangle = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
        graphicsContext?.fill(rectangle)
        let rectangleImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return rectangleImage!
    }
}

然后从您的 viewDidLoad() 方法调用 segmentedControl.addUnderlineForSelectedSegment() 之后,并为分段控件创建一个 @IBAction 方法,例如所以:

Then after call segmentedControl.addUnderlineForSelectedSegment() from your viewDidLoad() method, and create an @IBAction method for the segmented control like so:

@IBAction func segmentedControlDidChange(_ sender: UISegmentedControl){
        segmentedControl.changeUnderlinePosition()
    }

然后从该方法中调用 segmentedControl.changeUnderlinePosition().

Then call segmentedControl.changeUnderlinePosition() from within this method.

不要忘记将故事板中的分段控件连接到您刚刚创建的 @IBAction 方法.

Do not forget to connect the segmented control from your storyboard to the @IBAction method you just created.

非常重要:不要忘记在故事板中使用自动布局来确定分段控件的大小和位置.

Very important: Don't forget to use Auto layout in the storyboard to determine the size and position of your segmented control.

结果如下:

请随时提出您可能遇到的任何其他问题:)

Feel free to ask any other questions you may have :)

这篇关于如何在 UISegmentedControl 中仅显示所选项目的底部边框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆