1

を使用して、カスタムセグメント化されたコントロールを作成して問題私はカスタムを作成しようとしているベジェパス(スウィフト)

Segmented Control Mockup

下のモックにまで見られるように、私の検索コントローラの下に座っているコントロールをセグメント化:

私は、現在のインデックスを示すポイント針( "^"のように見える)を作成するのに問題があります。ソリューション

試み:以下の質問からいくつかの助けに

おかげで、私はそれが近くに見てもらうことができたが、私は

https://stackoverflow.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); 

    } 

} 

答えて

2

これを行う最も簡単な方法は不正行為です。ベジェ曲線で線を描く代わりに、高さ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を設定します。また、線幅と線の色を設定する必要があります。最後に、シェイプレイヤーをセグメント化されたコントロールのview.layerにサブレイヤーとして追加します。あなたが層に精通していない場合は、私はUIViewだけで説明した最初の方法を使用して簡単にそれを行う。 –

+0

これはすばらしい解決策でした!私は白い下の境界線を持つUIViewを使用するアプローチに行きました。助けてくれてありがとう、ジョシュ! –

関連する問題