自定义UISegmentedControl:如何更改所选片段图像的色调?

时间:2015-12-30 04:58:15

标签: ios swift uisegmentedcontrol

我已将此extension用于UISegmentedControl,因为您可以看到here.

但我希望UISegementedControl的工作略有不同。当我选择一个细分时,我希望所选细分的图像将颜色更改为colorGreyLight,而不是将背景颜色更改为colorGreyDark,并且选定的细分图像会更改为UIColor.clearColor() (你可以看到here

那我怎么能这样做呢?

我的代码

UISegmented Control Extension:

extension UISegmentedControl {
    func removeBorders() {
        setBackgroundImage(imageWithColor(UIColor.clearColor()), 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
    }
}

UISegemented Control:

    let types = ["rectangle", "circle", "triangle"]
    shapeSelector = UISegmentedControl(items: types)
    shapeSelector.frame = CGRectMake(0, 0, sliderHeight*3 + 30, sliderHeight)
    shapeSelector.center = CGPoint(x: drawToolbar.bounds.width/2, y: sliderCenterY)
    shapeSelector.tintColor = colorGreyDark
    shapeSelector.removeBorders()
    shapeSelector.selectedSegmentIndex = 0 //default: select rectangle
    shapeSelector.addTarget(self, action: "selectShape:", forControlEvents: .ValueChanged)
    shapeSelector.setImage(UIImage(named: "rectangle"), forSegmentAtIndex: 0)
    shapeSelector.setImage(UIImage(named: "circle"), forSegmentAtIndex: 1)
    shapeSelector.setImage(UIImage(named: "triangle"), forSegmentAtIndex: 2)
    shapeSelector.contentMode = UIViewContentMode.ScaleAspectFit
    drawToolbar.addSubview(shapeSelector)

如果我有任何疑虑,请使用:

  • IOS 9.2
  • Swift 2
  • Xcode 7.2

更新 好的,所以我按照Keyur的建议更改了我的代码(如下面的评论标记)

UISegmented Control Extension:

extension UISegmentedControl {
    func removeBorders() {
        setBackgroundImage(imageWithColor(UIColor.clearColor()), forState: .Normal, barMetrics: .Default)
        setBackgroundImage(imageWithColor(UIColor.clearColor()), forState: .Selected, barMetrics: .Default) //change to clear color
        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
    }
}

UISegemented Control:

    let types = ["rectangle", "circle", "triangle"]
    shapeSelector = UISegmentedControl(items: types)
    shapeSelector.frame = CGRectMake(0, 0, sliderHeight*3 + 30, sliderHeight)
    shapeSelector.center = CGPoint(x: drawToolbar.bounds.width/2, y: sliderCenterY)
    shapeSelector.tintColor = colorGreyDark
    shapeSelector.removeBorders()
    shapeSelector.selectedSegmentIndex = 0 //default: select rectangle
    (shapeSelector.subviews[0] as UIView).tintColor = colorGreyLight //added this line
    shapeSelector.addTarget(self, action: "selectShape:", forControlEvents: .ValueChanged)
    shapeSelector.setImage(UIImage(named: "rectangle"), forSegmentAtIndex: 0)
    shapeSelector.setImage(UIImage(named: "circle"), forSegmentAtIndex: 1)
    shapeSelector.setImage(UIImage(named: "triangle"), forSegmentAtIndex: 2)
    shapeSelector.contentMode = UIViewContentMode.ScaleAspectFit
    drawToolbar.addSubview(shapeSelector)

selectShape()功能:

func selectShape(sender: UISegmentedControl){
    switch sender.selectedSegmentIndex{
    case 0: //rectangle
        shapeType = "rectangle"
        (sender.subviews[0] as UIView).tintColor = colorGreyLight
        (sender.subviews[1] as UIView).tintColor = colorGreyDark
        (sender.subviews[2] as UIView).tintColor = colorGreyDark
    case 1: //circle
        shapeType = "circle"
        (sender.subviews[0] as UIView).tintColor = colorGreyDark
        (sender.subviews[1] as UIView).tintColor = colorGreyLight
        (sender.subviews[2] as UIView).tintColor = colorGreyDark
    case 2: //triangle
        shapeType = "triangle"
        (sender.subviews[0] as UIView).tintColor = colorGreyDark
        (sender.subviews[1] as UIView).tintColor = colorGreyDark
        (sender.subviews[2] as UIView).tintColor = colorGreyLight
    default:
        shapeType = "rectangle"
        (sender.subviews[0] as UIView).tintColor = colorGreyLight
        (sender.subviews[1] as UIView).tintColor = colorGreyDark
        (sender.subviews[2] as UIView).tintColor = colorGreyDark
    }
}

除非我尝试使用时,所选的形状并不总是突出显示的形状,因为您可以看到here。它似乎几乎随机地突出了形状,我不明白为什么。

对此的任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:3)

grep

答案 1 :(得分:1)

  1. 在removeborders()函数中设置颜色。
  2. setBackgroundImage(imageWithColor(UIColor.clearColor()),forState:.Normal,barMetrics:.Default)         setBackgroundImage(imageWithColor(UIColor.lightGrayColor()),forState:.Selected,barMetrics:.Default)

答案 2 :(得分:0)

感谢this post.

,我找到了答案

显然选择的索引不是分配色调颜色的可靠方法。相反,我必须自己跟踪细分。

这就是我在创建UISegmentedControl shapeSelector之后所做的事情:

var segments: [UIView] = [UIView]()
for i in 0...shapeSelector.subviews.count-1{
    segments.append(shapeSelector.subviews[i])
}

UISegmentedControl的功能中,我做了:

func selectShape(sender: UISegmentedControl){
    let i = sender.selectedSegmentIndex
    for s in segments{
        s.tintColor = colorGreyDark
    }
    segments[i].tintColor = colorGreyLight

    switch i{
    case 0:
        shapeType = "rectangle"
    case 1:
        shapeType = "circle"
    case 2:
        shapeType = "triangle"
    default:
        shapeType = "rectangle"
    }
}

现在一切都很完美!

完整代码

extension UISegmentedControl {
    func removeBorders() {
        setBackgroundImage(imageWithColor(UIColor.clearColor()), forState: .Normal, barMetrics: .Default)
        setBackgroundImage(imageWithColor(UIColor.clearColor()), 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
    }
}

class DrawViewController: UIViewController {

    var shapeSelector: UISegmentedControl = UISegmentedControl()
    var segments: [UIView] = [UIView]()

    override func viewDidLoad() {
        super.viewDidLoad()

        //set up shape selector
        let types = ["rectangle", "circle", "triangle"]
        shapeSelector = UISegmentedControl(items: types)
        shapeSelector.frame = CGRectMake(shapeTypeLabel.frame.maxX + sliderSpace, 0, sliderHeight*3 + 30, sliderHeight)
        shapeSelector.center.y = shapeTypeLabel.center.y
        shapeSelector.tintColor = colorGreyDark
        shapeSelector.removeBorders()
        shapeSelector.addTarget(self, action: "selectShape:", forControlEvents: .ValueChanged)
        shapeSelector.setImage(UIImage(named: "rectangle"), forSegmentAtIndex: 0)
        shapeSelector.setImage(UIImage(named: "circle"), forSegmentAtIndex: 1)
        shapeSelector.setImage(UIImage(named: "triangle"), forSegmentAtIndex: 2)
        for i in 0...shapeSelector.subviews.count-1{
            segments.append(shapeSelector.subviews[i])
        }
        shapeSelector.selectedSegmentIndex = 0 //default: select rectangle
        segments[0].tintColor = colorGreyLight
        shapeSelector.contentMode = UIViewContentMode.ScaleAspectFit
        drawToolbar.addSubview(shapeSelector)
    }

    func selectShape(sender: UISegmentedControl){
        let i = sender.selectedSegmentIndex
        for s in segments{
            s.tintColor = colorGreyDark
        }
        segments[i].tintColor = colorGreyLight

        switch i{
        case 0:
            shapeType = "rectangle"
        case 1:
            shapeType = "circle"
        case 2:
            shapeType = "triangle"
        default:
            shapeType = "rectangle"
        }
    }
}