快速创建自定义分段控件

大家好,这是我的第一个故事,与您分享ios分段控制。 ios中的默认边框带有边框和自定义功能,这并不容易。 如今,有些应用程序被设计为在Android和IOS上看起来一样,我们需要自定义许多组件,即使用户更换设备(IOS←→Android)也要给用户相同的体验。 因此,让我们创建一个分段控件,它看起来像Android中没有边框的选项卡式栏。 可以用作幻灯片菜单或XLPagerTabStrip中的滑块标签,也可以用作Android中带有滚动标签的滑块标签。 我通过观看Mark Tutorial youtube频道创建了此自定义分段控件,并根据我的要求进行了更多自定义。 让我们深入研究代码…


  1. 众所周知,UIControl继承自UIView。 所有IOS或Xcode UIComponent都继承自UIControl,后者已封装或绑定了组件的所有操作和侦听器(UIControlEvents,如.tpuchUpInside,.changeValue等)。

因此,为customSegmentedControl创建一个UIControl的子类。

@IBDesignable类CustomSegmentedContrl:UIControl {

}

2.现在,添加按钮数组,其作用类似于段。 要突出显示所选按钮/细分,我们可以使用单独的视图。 在这里,我称其为“选择器”。 我还在细分控件的底部放置了底层视图

var按钮= [UIButton]()

var underLiner:UIView!

var选择器:UIView!

3.在这里,我给出一个选项,选择带有标志的衬板。

var isUnderLinerNeeded:Bool = false {

didSet {

updateView()

}

}

4.在这里,还有两个可以用于分段控件的属性

var selectedSegmentIndex = 0 {

didSet {

updateSegmentedControlSegs(index:selectedSegmentIndex)

}

}

var numberOfSegments:Int = 0 {

didSet {

numberOfSegments = button.count

}

}

5.在这里,添加了创建自定义分段控件所需的所有@IBInspectables

@IBInspectable var borderWidth:CGFloat = 0 {

didSet {

layer.borderWidth = borderWidth

}

}

@IBInspectable var cornerRadius:CGFloat = 0 {

didSet {

layer.cornerRadius = cornerRadius

}

}

@IBInspectable var borderColor:UIColor = .clear {

didSet {

layer.borderColor = borderColor.cgColor

}

}

@IBInspectable var commaSeperatedButtonTitles:字符串=“” {

didSet {

updateView()

}

}

@IBInspectable var textColor:UIColor = .lightGray {

didSet {

updateView()

}

}

@IBInspectable var选择器颜色:UIColor = .darkGray {

didSet {

updateView()

}

}

@IBInspectable var selectorTextColor:UIColor = .green {

didSet {

updateView()

}

}

6.在这里,我添加了init和Required inits

覆盖init(frame:CGRect){

super.init(frame:框架)

updateView()

}

需要初始化吗?(编码器aDecoder:NSCoder){

super.init(编码器:aDecoder)

fatalError(“ init(coder :)尚未实现”)

}

7.在选择所有那些IBInspectables和其他属性后,我在这里将函数称为“ updateView”。

  • >在此方法中,每次调用此方法时,我们都会删除所有按钮。 否则,它将在每次方法调用时一次又一次地添加这些按钮。
  • >我们从“ commaSeperatedButtonTitles”获得按钮标题,这也是IBInspectable属性。 所有标题都需要以逗号分隔。 对于前{“ title1,title2,title3”}
  • >在获取按钮标题之后,我们将它们提取到数组中,然后为每个标题创建按钮并将它们添加到堆栈视图中。 在这里,我们还添加了一个选择器视图,该视图在选择分段时突出显示。 如果用户需要通过访问flag属性来设置underliner View。
  • >选择此处的细分/按钮时,我们添加了一个称为“ @objc func buttonTapped(button:UIButton){}”的“ addTarget方法”作为选择器,以更新选择器位置并更新所选按钮的内容。

func updateView(){

button.removeAll()

subviews.forEach {(view in in

view.removeFromSuperview()

}

让buttonTitles = commaSeperatedButtonTitles.components(separatedBy:“,”)

对于buttonTitle中的buttonTitle {

let button = UIButton.init(type:.system)

button.setTitle(buttonTitle,用于:.normal)

button.titleLabel?.font = UIFont.init(名称:“系统粗体”,大小:18)

button.setTitleColor(textColor,for:.normal)

button.addTarget(self,action:#selector(buttonTapped(button :)),用于:.touchUpInside)

button.append(按钮)

// button.setTitleColor(button.isSelected?UIColor.gray:selectorTextColor,用于:.normal)

}

numberOfSegments = button.count

button [0] .setTitleColor(selectorTextColor,for:.normal)

//对于UnderLiner对于SegmentedController

如果isUnderLinerNeeded {

underLiner = UIView.init()

underLiner.backgroundColor = unSelectedColor

addSubview(underLiner)

underLiner.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([

underLiner.leadingAnchor.constraint(equalTo:self.leadingAnchor,常数:0),

underLiner.trailingAnchor.constraint(equalTo:self.trailingAnchor,常数:0),

underLiner.heightAnchor.constraint(equalToConstant:2.0),

underLiner.topAnchor.constraint(等于:self.bottomAnchor,常数:-2.0)

])

}

让selectorWidth = frame.width / CGFloat(buttonTitles.count)

令y =(self.frame.maxY — self.frame.minY)— 3.0

选择器= UIView.init(框架:CGRect.init(x:0,y:y,宽度:selectorWidth,高度:3.0))

//选择器.layer.cornerRadius = frame.height / 2

selector.backgroundColor = selectorColor

addSubview(选择器)

//创建一个StackView

让stackView = UIStackView.init(arrangedSubviews:按钮)

stackView.axis = .horizo​​ntal

stackView.alignment = .fill

stackView.distribution = .fillEqually

stackView.spacing = 0.0

addSubview(stackView)

stackView.translatesAutoresizingMaskIntoConstraints = false

stackView.topAnchor.constraint(equalTo:self.topAnchor).isActive = true

stackView.bottomAnchor.constraint(等于:self.bottomAnchor).isActive = true

stackView.leftAnchor.constraint(equalTo:self.leftAnchor).isActive = true

stackView.rightAnchor.constraint(equalTo:self.rightAnchor).isActive = true

}

8.此处,用于操作和带有段更改的更新段控制的其余代码(与IBActions同步)

  • >“ func updateSegmentedControlSegs(index:Int){}”是通过传递索引参数/参数来更改分段的辅助方法。 在使用UIPageViewController或根据分段控件使用的任何其他视图时,它将很有用。
  • ->最后,最后,我们重写controlEvents的sendActions方法,以发送动作。

@objc func buttonTapped(button:UIButton){

var selectorStartPosition:CGFloat!

对于button.enumerated()中的(buttonIndex,btn){

btn.setTitleColor(textColor,for:.normal)

如果btn ==按钮{

selectedSegmentIndex = buttonIndex

selectorStartPosition = frame.width / CGFloat(buttons.count)* CGFloat(buttonIndex)

UIView.animate(withDuration:0.3,动画:{

self.selector.frame.origin.x = selectorStartPosition

})

btn.setTitleColor(selectorTextColor,for:.normal)

}

}

sendActions(for:.valueChanged)

}

func updateSegmentedControlSegs(index:Int){

var selectorStartPosition:CGFloat!

用于按钮中的btn {

btn.setTitleColor(textColor,for:.normal)

}

selectorStartPosition = frame.width / CGFloat(buttons.count)* CGFloat(index)

UIView.animate(withDuration:0.3,动画:{

self.selector.frame.origin.x = selectorStartPosition

})

button [index] .setTitleColor(selectorTextColor,用于:.normal)

}

覆盖func sendActions(用于controlEvents:UIControlEvents){

super.sendActions(用于:controlEvents)

var selectorStartPosition:CGFloat!

selectorStartPosition = frame.width / CGFloat(buttons.count)* CGFloat(selectedSegmentIndex)

UIView.animate(withDuration:0.3,动画:{

self.selector.frame.origin.x = selectorStartPosition

})

button [selectedSegmentIndex] .setTitleColor(selectorTextColor,用于:.normal)

}

9.最后,创建您的自定义分段控件:

func createSegmentedControl(){

segmentedControl = CustomSegmentedContrl.init(frame:CGRect.init(x:0,y:self.topView.frame.maxY + 10,width:self.view.frame.width,height:45))

// segmentedControl

segmentedControl.backgroundColor = .white

segmentedControl.commaSeperatedButtonTitles =“标题1,标题2,标题3”

segmentedControl.addTarget(self,action:#selector(onChangeOfSegment(_ :)),for:.valueChanged)

segmentedControl.selectedSegmentIndex = 0

segmentedControl.textColor = UIColor.red

segmentedControl.selectorTextColor = UIColor.blue!

segmentedControl.isUnderLinerNeeded = true

self.view.addSubview(segmentedControl)

}

类文件链接在这里。

谢谢阅读!!!