Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 用swift制作多色条_Ios_Swift - Fatal编程技术网

Ios 用swift制作多色条

Ios 用swift制作多色条,ios,swift,Ios,Swift,我试着画一条线(基本上是UIView),它有固定的高度和宽度,被分成九段。我希望能够控制每个片段的高度及其颜色。例如,我希望第一段为黄色,占线路总高度的30%,第二段为红色,占线路总高度的8%,等等 我不太擅长Swift,所以我的解决方案是制作9个UIView,将它们堆叠在我的故事板上,然后手动设置每个视图的高度和背景色,使它们看起来像一条多色线。是否有更干净、体积更小的解决方案?谢谢我强烈建议您为此使用核心图形。 由于绘图非常简单(您只想在视图中堆叠一些彩色线条),您可以通过子类化UIView

我试着画一条线(基本上是UIView),它有固定的高度和宽度,被分成九段。我希望能够控制每个片段的高度及其颜色。例如,我希望第一段为黄色,占线路总高度的30%,第二段为红色,占线路总高度的8%,等等

我不太擅长Swift,所以我的解决方案是制作9个UIView,将它们堆叠在我的故事板上,然后手动设置每个视图的高度和背景色,使它们看起来像一条多色线。是否有更干净、体积更小的解决方案?谢谢

我强烈建议您为此使用核心图形。 由于绘图非常简单(您只想在视图中堆叠一些彩色线条),您可以通过子类化
UIView
并覆盖
drawRect()
并在核心图形中绘制它们来轻松实现这一点。

这肯定是一个比添加9个子视图更干净的解决方案

这样的东西应该能达到预期的效果:

class LineView : UIView {

    let colors:[UIColor] = [UIColor.redColor(), UIColor.blueColor(), UIColor.greenColor()]
    let values:[CGFloat] = [0.35, 0.45, 0.2]

    override func drawRect(rect: CGRect) {

        let r = self.bounds // the view's bounds
        let numberOfSegments = values.count // number of segments to render

        let ctx = UIGraphicsGetCurrentContext() // get the current context

        var cumulativeValue:CGFloat = 0 // store a cumulative value in order to start each line after the last one
        for i in 0..<numberOfSegments {

            CGContextSetFillColorWithColor(ctx, colors[i]) // set fill color to the given color
            CGContextFillRect(ctx, CGRectMake(0, cumulativeValue*r.size.height, r.size.width, values[i]*r.size.height)) // fill that given segment

            cumulativeValue += values[i] // increment cumulative value
        }
    }
}
class LineView : UIView {

    /// An array of optional UIColors (clearColor is used when nil is provided) defining the color of each segment.
    var colors : [UIColor?] = [UIColor?]() {
        didSet {
            self.setNeedsDisplay()
        }
    }

    /// An array of CGFloat values to define how much of the view each segment occupies. Should add up to 1.0.
    var values : [CGFloat] = [CGFloat]() {
        didSet {
            self.setNeedsDisplay()
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = UIColor.clearColor()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func drawRect(rect: CGRect) {

        let r = self.bounds // the view's bounds
        let numberOfSegments = values.count // number of segments to render

        let ctx = UIGraphicsGetCurrentContext() // get the current context

        var cumulativeValue:CGFloat = 0 // store a cumulative value in order to start each line after the last one
        for i in 0..<numberOfSegments {

            CGContextSetFillColorWithColor(ctx, colors[i]?.CGColor ?? UIColor.clearColor().CGColor) // set fill color to the given color if it's provided, else use clearColor
            CGContextFillRect(ctx, CGRectMake(0, cumulativeValue*r.size.height, r.size.width, values[i]*r.size.height)) // fill that given segment

            cumulativeValue += values[i] // increment cumulative value
        }
    }
}
let lineView = LineView(frame: CGRectMake(50, 50, 20, view.bounds.size.height-100))

lineView.colors = [
    UIColor(red: 1.0, green: 31.0/255.0, blue: 73.0/255.0, alpha: 1.0), // red
    UIColor(red:1.0, green: 138.0/255.0, blue: 0.0, alpha:1.0), // orange
    UIColor(red: 122.0/255.0, green: 108.0/255.0, blue: 1.0, alpha: 1.0), // purple
    UIColor(red: 0.0, green: 100.0/255.0, blue: 1.0, alpha: 1.0), // dark blue
    UIColor(red: 100.0/255.0, green: 241.0/255.0, blue: 183.0/255.0, alpha: 1.0), // green
    UIColor(red: 0.0, green: 222.0/255.0, blue: 1.0, alpha: 1.0) // blue
]
lineView.values = [0.15, 0.1, 0.35, 0.15, 0.1, 0.15]

view.addSubview(lineView);
用法:

class LineView : UIView {

    let colors:[UIColor] = [UIColor.redColor(), UIColor.blueColor(), UIColor.greenColor()]
    let values:[CGFloat] = [0.35, 0.45, 0.2]

    override func drawRect(rect: CGRect) {

        let r = self.bounds // the view's bounds
        let numberOfSegments = values.count // number of segments to render

        let ctx = UIGraphicsGetCurrentContext() // get the current context

        var cumulativeValue:CGFloat = 0 // store a cumulative value in order to start each line after the last one
        for i in 0..<numberOfSegments {

            CGContextSetFillColorWithColor(ctx, colors[i]) // set fill color to the given color
            CGContextFillRect(ctx, CGRectMake(0, cumulativeValue*r.size.height, r.size.width, values[i]*r.size.height)) // fill that given segment

            cumulativeValue += values[i] // increment cumulative value
        }
    }
}
class LineView : UIView {

    /// An array of optional UIColors (clearColor is used when nil is provided) defining the color of each segment.
    var colors : [UIColor?] = [UIColor?]() {
        didSet {
            self.setNeedsDisplay()
        }
    }

    /// An array of CGFloat values to define how much of the view each segment occupies. Should add up to 1.0.
    var values : [CGFloat] = [CGFloat]() {
        didSet {
            self.setNeedsDisplay()
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = UIColor.clearColor()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func drawRect(rect: CGRect) {

        let r = self.bounds // the view's bounds
        let numberOfSegments = values.count // number of segments to render

        let ctx = UIGraphicsGetCurrentContext() // get the current context

        var cumulativeValue:CGFloat = 0 // store a cumulative value in order to start each line after the last one
        for i in 0..<numberOfSegments {

            CGContextSetFillColorWithColor(ctx, colors[i]?.CGColor ?? UIColor.clearColor().CGColor) // set fill color to the given color if it's provided, else use clearColor
            CGContextFillRect(ctx, CGRectMake(0, cumulativeValue*r.size.height, r.size.width, values[i]*r.size.height)) // fill that given segment

            cumulativeValue += values[i] // increment cumulative value
        }
    }
}
let lineView = LineView(frame: CGRectMake(50, 50, 20, view.bounds.size.height-100))

lineView.colors = [
    UIColor(red: 1.0, green: 31.0/255.0, blue: 73.0/255.0, alpha: 1.0), // red
    UIColor(red:1.0, green: 138.0/255.0, blue: 0.0, alpha:1.0), // orange
    UIColor(red: 122.0/255.0, green: 108.0/255.0, blue: 1.0, alpha: 1.0), // purple
    UIColor(red: 0.0, green: 100.0/255.0, blue: 1.0, alpha: 1.0), // dark blue
    UIColor(red: 100.0/255.0, green: 241.0/255.0, blue: 183.0/255.0, alpha: 1.0), // green
    UIColor(red: 0.0, green: 222.0/255.0, blue: 1.0, alpha: 1.0) // blue
]
lineView.values = [0.15, 0.1, 0.35, 0.15, 0.1, 0.15]

view.addSubview(lineView);

(我在这里只添加了6种颜色,但您可以添加任意数量的颜色)


完整项目:

我刚刚意识到这不是您需要的。 不管怎样,我留下了答案,以便将来可能对其他人有所帮助

确保您的线视图有自己的UIView子类,这样我们就可以覆盖
drawRect
并实现您的目标

那么一个简单的实现就是:

class BarLine: UIView {

    override func drawRect(rect: CGRect) {

        //Height of each segment, in percentage
        var heights  : [CGFloat]    = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

        //Lets create 9 rects and set each rect width to be 1/9th of the view size, then add them to the array
        let width   : CGFloat   = rect.size.width / 9.0


        var i       : Int       = Int()

        //Loop to generate 9 segmnets
        for (i = 0; i < 9; i++) {

            //Each rect origin must be translated by i * width
            let origin  = CGPointMake(CGFloat(i) * width, rect.height)

            //Generate a random color
            let color   = UIColor(red: heights[i], green: 0.5, blue: 0.5, alpha: 1)
            let segment = CGRect(x: origin.x, y: origin.y, width: width, height: -heights[i] * rect.height)

            //Set the color
            color.set()

            //Add the segment to the view by drawing it
            UIRectFill(segment)

        }


    }

}
class条线:UIView{
重写func drawRect(rect:CGRect){
//每段的高度,以百分比表示
变量高度:[CGFloat]=[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]
//让我们创建9个矩形,并将每个矩形宽度设置为视图大小的1/9,然后将它们添加到数组中
let width:CGFloat=rect.size.width/9.0
变量i:Int=Int()
//循环以生成9个segmnet
对于(i=0;i<9;i++){
//每个rect原点必须转换为i*宽度
让原点=CGPointMake(CGFloat(i)*宽度,矩形高度)
//生成随机颜色
让颜色=UIColor(红色:高度[i],绿色:0.5,蓝色:0.5,alpha:1)
设线段=CGRect(x:origin.x,y:origin.y,width:width,height:-heights[i]*rect.height)
//设置颜色
color.set()
//通过绘制线段将其添加到视图中
UIRectFill(段)
}
}
}
这将产生如下结果:

(记住将UIView类设置为IB中的自定义类)

我希望这有助于

使@code与Swift 5兼容,这里是LineView类(并在draw->fill中反转宽度和高度以使其水平):

导入UIKit
公共类ColorLineView:UIView{
公共变量颜色:[UIColor?]=[UIColor?](){
迪塞特{
self.setNeedsDisplay()
}
}
公共变量值:[CGFloat]=[CGFloat](){
迪塞特{
self.setNeedsDisplay()
}
}
公共重写初始化(帧:CGRect){
super.init(frame:frame)
背景颜色=.clear
}
必需的初始化?(编码器aDecoder:NSCoder){
super.init(编码者:aDecoder)
}
公共覆盖函数绘图(rect:CGRect){
设r=自界
让numberOfSegments=values.count
guard let ctx=UIGraphicsGetCurrentContext()else{return}
var累积值:CGFloat=0

我在0 ..解决方案听起来不错,但考虑比例约束,你只是做简单的绘图在这里(只是多个颜色堆叠在对方),我将研究重写
drawRect
并在核心图形中绘制线条。这肯定是一个比创建9个单独的子视图更干净的解决方案。@originaluser2是的,就是这个。可以对您的解决方案进行一点扩展吗?为了补充@originaluser2所说的内容,这里有一个关于核心图形的教程@EmilioPelaez,谢谢,我们将对此进行研究。@sh4rPEYE很乐意提供帮助!我们如何才能为此创建多行代码?这仍然是一个令人钦佩的答案,即使这不是OP想要的;)