使用贝塞尔路径(SWIFT)

问题描述:

我试图创建一个自定义分段,坐在我的搜索控制器的控制下在模拟看到了下面使用贝塞尔路径(SWIFT)

Segmented Control Mockup

问题创建自定义分段控制:

我很难创建指示当前索引的尖针(看起来像这样:“^”)。

在尝试解决

由于从下面的问题一些帮助,我能够让它看起来很近,但我无法得到的指针显示

https://*.com/a/37705692/5254240

enter image description here

问:

如何让我的代码看起来像我目前拥有的样机,并获得指针以与分段控制器的当前索引一起移动?看到我的代码如下

func imageWithColor(color: UIColor) -> UIImage { 

    let rect = CGRectMake(0.0, 0.0, 1.0, segmentedController.frame.size.height) 
    UIGraphicsBeginImageContext(rect.size) 
    let context = UIGraphicsGetCurrentContext() 
    CGContextSetFillColorWithColor(context, color.CGColor); 
    CGContextFillRect(context, rect); 
    let image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return image 

} 

func initializeSearchController() { 
    segmentedController.setTitleTextAttributes([NSFontAttributeName:UIFont(name: "Lato-Regular", size: 14)!,NSForegroundColorAttributeName:UIColor.init(red: 143/255, green: 142/255, blue: 148/255, alpha: 1.0)], forState:UIControlState.Normal) 

    segmentedController.setTitleTextAttributes([NSFontAttributeName:UIFont(name: "Lato-Bold", size: 14)!,NSForegroundColorAttributeName:UIColor.init(red: 93/255, green: 176/255, blue: 175/255, alpha: 1.0)], forState:UIControlState.Selected) 

    segmentedController.setDividerImage(self.imageWithColor(UIColor.clearColor()), forLeftSegmentState: UIControlState.Normal, rightSegmentState: UIControlState.Normal, barMetrics: UIBarMetrics.Default) 

    segmentedController.setBackgroundImage(self.imageWithColor(UIColor.clearColor()), forState:UIControlState.Normal, barMetrics:UIBarMetrics.Default) 

    segmentedController.setBackgroundImage(self.imageWithColor(UIColor.clearColor()), forState:UIControlState.Selected, barMetrics:UIBarMetrics.Default) 

    segmentedController.setTitle("Search", forSegmentAtIndex: 0) 
    segmentedController.setTitle("Meals", forSegmentAtIndex: 1) 

    for borderview in segmentedController.subviews { 

     let upperBorder: CALayer = CALayer() 
     upperBorder.backgroundColor = UIColor.init(red: 93/255, green: 176/255, blue: 175/255, alpha: 1.0).CGColor 
     upperBorder.frame = CGRectMake(0, borderview.frame.size.height-1, borderview.frame.size.width, 1.0); 
     borderview.layer.addSublayer(upperBorder); 

    } 

} 

最简单的方法就是作弊。您可以使用高度为1的UIView绘制实线,而不是使用贝塞尔曲线绘制线条。使用PhotoShop中实心白底的三角形作为图像并将其放在线条的顶部。现在要为位置设置动画,您可以更改其变形,更新其中心或使用自动布局约束,并且它会滑入新位置。例如:

UIView.animate(withDuration: 0.25) { 
    triangeImageView.center.x = selectedLabel.center.x 
} 

您当然也可以使用CAShapeLayer以编程方式执行此操作。您将构建您的路径使用的线沿线的东西:

let bezierPath = UIBezierPath() 
bezierPath.move(to: CGPoint(x: left, y: bottom)) 
bezierPath.addLine(to: CGPoint(x: centerX + triangleWidth/2, y: top)) 
bezierPath.addLine(to: CGPoint(x: centerX, y: top - triangleHeight)) 
bezierPath.addLine(to: CGPoint(x: centerX - triangleWidth/2, y: top)) 
bezierPath.addLine(to: CGPoint(x: left, y: top)) 
bezierPath.close() 

然后你可以使用一个CABasicAnimation从旧路径到新的动画路径。由于您按照相同的顺序构建点,动画系统将插入该位置,并且三角形将显示为滑入位置。

+0

谢谢,乔希。所以我继续前进,试图用bezeirPath画线,看看我是否可以通过编程工作,但我不确定如何将CAShapeLayer添加到我的分段控件中。在创建路径之后,如何让它在分段控件中“显示”? –

+0

您需要在viewDidLayoutSubviews中创建图层,以便它始终正确调整大小。 (即如果图层存在,removeFromSuperlayer并创建一个新的CAShape图层),设置shapeLayer.path = bezierPath.cgPath。您还需要设置lineWidth和笔触颜色。最后,将您的形状图层作为子图层添加到您的分段控件的view.layer中。如果你对图层不熟悉,那么使用我只用UIView描述的第一种方法来做它更容易。 –

+0

这是一个绝妙的解决方案!我采用了带有白底边框的UIView的方法。感谢所有的帮助,乔希! –