美文网首页
Siwft中使用UIView自定义控件

Siwft中使用UIView自定义控件

作者: MangoJ | 来源:发表于2016-12-07 17:24 被阅读26次

使用View自定义SegmentControl

为了能让大家更好的学习自定义控件,我将详细讲解每一步,闲话少说进入今天的主题!

基本步骤及每步的思想如下:

首先我们要确定我们要实现的功能及效果,"分段选择器"类似于系统的UISegmentControl
效果图如下:
(被选中的水果选项其字体变为橙色下方的橙色线条也移动到相应的位置)

1.png

首先,我们需要考虑用哪些系统控件来实现这样的效果,看图分析,我们需要(1)创建底部视图,(2)水果标签及(3)标签下的黄色细线,综合考虑,我们(1)使用UIScrollView,(2)使用UILabel,(3)使用UIView

1.创建一个新类,基类选择UIView
2.实现init(frame:)方法

 class MangoJPageViewControl: UIView {
       init(frame : CGRect){
      super.init(frame : frame)
    }
       required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

3.初始化控件 设置属性 定义协议 设置代理
使用代理 获得所选标签

 // MARK:- 代理1
protocol  PageTitleViewDelegate :class{
func pageTitleView(_ titleView : MCustomPageTitleView, selectedIndex index : Int)
}
class MangoJPageViewControl: UIView {
//MARK:-  代理2
weak var delegate : PageTitleViewDelegate?

fileprivate var titles :[String] = []
fileprivate lazy var titleLabels : [UILabel] = [UILabel]()
fileprivate lazy var scrollView:UIScrollView = UIScrollView()
fileprivate lazy var scrollLine : UIView = UIView()
fileprivate var currentLabelIndex :Int = 0


init(frame: CGRect,titles:[String]) {
    super.init(frame: frame)
    self.titles = titles
    setupUI()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


}

4.设置控件布局

extension MangoJPageViewControl{

func setupUI()  {

    setupScrollView()
    setupTitleLabels()
    setupLineView()
    setupBottomAndLine()
}

 fileprivate func setupScrollView()  {
    scrollView.showsHorizontalScrollIndicator = false
    scrollView.frame = bounds
    scrollView.scrollsToTop = false
    scrollView.isPagingEnabled = false
    scrollView.bounces = false
}

fileprivate func setupTitleLabels(){
    let label_W :CGFloat = frame.width / CGFloat(titles.count)
    let label_H :CGFloat = frame.height - kScrollLineH
    let label_Y :CGFloat = 0
    
    for (index,title) in titles.enumerated() {
        let label = UILabel()
        label.text = title
        label.tag = index
        label.font = UIFont.systemFont(ofSize: 15)
        label.textColor = UIColor(r: kNormalColor.0, g: kNormalColor.1, b: kNormalColor.2)
        label.textAlignment = .center
        let label_X :CGFloat = label_W * CGFloat(index)
        label.frame = CGRect(x: label_X, y: label_Y, width: label_W, height: label_H)
        scrollView.addSubview(label)
        titleLabels.append(label)
        
        //给label添加手势
        label.isUserInteractionEnabled = true
        let tapGes = UITapGestureRecognizer(target: self, action: #selector(titleLabelClick))
        label.addGestureRecognizer(tapGes)
    }    
}
fileprivate func setupLineView(){
    scrollLine.backgroundColor = UIColor.orange
//设置默认选中的第一个
   guard let firstLabel = titleLabels.first else { return }
    firstLabel.textColor = UIColor(r: kSelectColor.0, g: kSelectColor.1, b: kSelectColor.2)
    scrollView.addSubview(scrollLine)
    scrollLine.frame = CGRect(x: firstLabel.frame.origin.x+firstLabel.frame.width*0.1, y: frame.height-kScrollLineH, width: firstLabel.frame.width*0.8, height: kScrollLineH)
}

fileprivate func setupBottomAndLine(){
    let bottomLine = UIView()
    bottomLine.backgroundColor = UIColor.lightGray
    bottomLine.frame = CGRect(x: 0, y: frame.height - lineH, width: frame.width, height: lineH)
    addSubview(bottomLine)
 
}
}


extension MangoJPageViewControl{
  @objc fileprivate func titleLabelClick(tap:UITapGestureRecognizer){
    guard  let currentLabel = tap.view as? UILabel else {
        return
    }
    
    if currentLabel.tag == currentLabelIndex {
        return
    }
    let oldLabel = titleLabels[currentLabelIndex]
    currentLabel.textColor = UIColor(r: kSelectColor.0, g: kSelectColor.1, b: kSelectColor.2)
    oldLabel.textColor = UIColor(r: kNormalColor.0, g: kNormalColor.1, b: kNormalColor.2)
    currentLabelIndex = currentLabel.tag
   let scrollLinePosition = currentLabel.frame.origin.x
    scrollLine.frame.size.width = currentLabel.frame.width * 0.8
    UIView.animate(withDuration: 0.2, animations: {
        self.scrollLine.frame.origin.x = scrollLinePosition//X
    })

    //MARK:-  代理3
    delegate?.pageTitleView(self, selectedIndex: currentLabelIndex)
}
}



//公开给外面调用的FUNC

extension MangoJPageViewControl{

func setTitleWithProgress(_ progress:CGFloat,sourceIndex : Int,targetIndex : Int){
    let sourceLabel = titleLabels[sourceIndex]
    let targetLabel = titleLabels[targetIndex]
    let moveTotalX = targetLabel.frame.origin.x - sourceLabel.frame.origin.x
    let moveX = moveTotalX * progress
    scrollLine.frame.origin.x = sourceLabel.frame.origin.x + sourceLabel.frame.width*0.1 + moveX
    
    let colorDelta = (kSelectColor.0 - kNormalColor.0,kSelectColor.1 - kNormalColor.1,kSelectColor.2 - kNormalColor.2)
    sourceLabel.textColor = UIColor(r: kSelectColor.0 - colorDelta.0 * progress, g: kSelectColor.1 - colorDelta.1 * progress, b: kSelectColor.2 - colorDelta.2 * progress)
    targetLabel.textColor = UIColor(r: kNormalColor.0 + colorDelta.0 * progress, g: kNormalColor.1 + colorDelta.1 * progress, b: kNormalColor.2 + colorDelta.2 * progress)
    //
    currentLabelIndex = targetIndex
}
}
自定义控件完成

简单的调用如下:

import UIKit

class ViewController: UIViewController,PageTitleViewDelegate {

override func viewDidLoad() {
    super.viewDidLoad()

    let pageView :MangoJPageViewControl
    let titles = ["香蕉","苹果","橘子","大鸭梨"]
    pageView = MangoJPageViewControl(frame: CGRect(x: 0, y: 100, width: UIScreen.main.bounds.width, height: 40), titles: titles)
    pageView.delegate = self
    view.addSubview(pageView)
    
}

//设置代理方法
func pageTitleView(_ titleView: MangoJPageViewControl, selectedIndex index: Int) {
    //可以获取到所选项的index
}


}

相关文章

网友评论

      本文标题:Siwft中使用UIView自定义控件

      本文链接:https://www.haomeiwen.com/subject/ogvdmttx.html