【问题标题】:How to create a custom segment control in Swift如何在 Swift 中创建自定义分段控件
【发布时间】:2018-10-22 22:02:10
【问题描述】:

我想创建一个像屏幕截图中那样工作的分段控件。 所选段应根据段标题文本加下划线。我已经搜索过了,但没有找到任何第三方解决方案。 那么如何开发这种类型的段控制呢?

在这里您可以看到底部的线只延伸到选定的段。

【问题讨论】:

  • 你检查过这个github.com/kitasuke/PagingMenuController ??您可以使用第三方并根据需要进行自定义。
  • @iOS.Walf 我检查了,但我希望如果我选择任何段索引,底线应该具有所选段标签文本包含的确切宽度。

标签: ios iphone swift uisegmentedcontrol


【解决方案1】:

GitHub 中有一个名为PageMenu 的开源项目。请看一下,你甚至可以自定义源文件CAPSPageMenu

https://github.com/PageMenu/PageMenu

要更新选择细线的宽度,请启用以下属性。

menuItemWidthBasedOnTitleTextWidth

代码:

let parameters: [CAPSPageMenuOption] = [ 
... 
.menuItemWidthBasedOnTitleTextWidth(true),
....]

// Initialize scroll menu
pageMenu = CAPSPageMenu(viewControllers: controllerArray, frame: CGRect(x: 0.0, y: 0.0, width: self.view.frame.width, height: self.view.frame.height), pageMenuOptions: parameters)

请在项目中尝试PageMenuDemoStoryboard 演示并更新parameters 如上代码所示。

【讨论】:

  • 我想要分段控制,这样底部选定的视图应该随着标签内容的增加而增加。
  • 不要使用这个库,它有超过 300 个未解决的问题,最后一次提交是 3 年前!
  • 它的库维护不好
【解决方案2】:
    import UIKit

extension UIView {
    func constraintsEqualToSuperView() {
        if let superview = self.superview {
            NSLayoutConstraint.activate(
                [
                    self.topAnchor.constraint(
                        equalTo: superview.topAnchor
                    ),
                    self.bottomAnchor.constraint(
                        equalTo: superview.bottomAnchor
                    ),
                    self.leadingAnchor.constraint(
                        equalTo: superview.leadingAnchor
                    ),
                    self.trailingAnchor.constraint(
                        equalTo: superview.trailingAnchor
                    )
                ]
            )
        }
    }
}

protocol ButtonsViewDelegate: class {
    func didButtonTap(buttonView: ButtonsView, index: Int)
}

class ButtonsView: UIView {

    fileprivate let stackView         = UIStackView()
    fileprivate var array             = [String]()
    fileprivate var buttonArray       = [UIButton]()
    fileprivate let baseTag = 300
    weak var delegate: ButtonsViewDelegate?

    override init(frame: CGRect) {
        super.init(frame: frame)

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

    fileprivate func setupUI () {
        setupStackView()
        setupButton()
    }


    convenience init(buttons: [String]) {
        self.init()
        array = buttons
        setupUI()
        //selectButton(atIndex: 0)
    }


    fileprivate func setupStackView() {
        addSubview(stackView)
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.distribution = .fillEqually
        stackView.constraintsEqualToSuperView()
    }

    fileprivate func setupButton() {
        for (i,string) in array.enumerated() {
            let button = UIButton()
            button.setTitle(string.uppercased(), for: .normal)
//            button.backgroundColor = UIColor.lightBackgroundColor().lightened(by: 0.2)
            button.translatesAutoresizingMaskIntoConstraints = false
            button.addTarget(
                self,
                action: #selector(buttonClicked(sender:)),
                for: .touchUpInside
            )
            button.setTitleColor(
                .black,
                for: .normal
            )
            button.titleLabel?.font = UIFont.systemFont(
                ofSize: 14,
                weight: UIFont.Weight.bold
            )

//            let view = UIView.init(frame: CGRect.init(x: 0, y: button.frame.size.height - 1, width: button.frame.size.width, height: 1))

            let view = UIView()
            view.translatesAutoresizingMaskIntoConstraints = false
            view.backgroundColor = UIColor.clear
            view.tag = baseTag + i
            button.addSubview(view)
            NSLayoutConstraint.activate([
                view.leadingAnchor.constraint(
                    equalTo: button.leadingAnchor
                ),
                view.trailingAnchor.constraint(
                    equalTo: button.trailingAnchor
                ),
                view.bottomAnchor.constraint(
                    equalTo: button.bottomAnchor
                ),
                view.heightAnchor.constraint(
                    equalToConstant: 1
                )
            ])

            stackView.addArrangedSubview(button)
            buttonArray.append(button)
        }
    }

    func selectButton(atIndex index: Int) {
        if index <= buttonArray.count {
            buttonClicked(sender: buttonArray[index])
        }
    }

    @objc private func buttonClicked(sender: UIButton) {
        for button in buttonArray {
            if button == sender {
                button.setTitleColor(
                    UIColor.darkGray,
                    for: .normal
                )
               setUpBottomLine(button: button)
            }else{
                button.setTitleColor(
                    .black,
                    for: .normal
                )
               hideBottomLine(button: button)
            }
        }

        if let index = buttonArray.index(of: sender) {
            delegate?.didButtonTap(buttonView: self, index: index)
        }
    }

    private func setUpBottomLine(button: UIButton) {
        if let index = buttonArray.index(of: button) {
            if let view = button.viewWithTag(baseTag + index) {
                view.backgroundColor = UIColor.red
            }
        }
    }

    private func hideBottomLine(button: UIButton) {
        if let index = buttonArray.index(of: button) {
            if let view = button.viewWithTag(baseTag + index) {
                view.backgroundColor = .clear
            }
        }
    }
}

//how to use
let durationBtns = ButtonsView(buttons: [
    NSLocalizedString(
        "day",
        comment: ""
    ),
    NSLocalizedString(
        "week",
        comment: ""
    ),
    NSLocalizedString(
        "month",
        comment: ""
    ),
    NSLocalizedString(
        "year",
        comment: ""
    )
    ])
durationButtons = durationBtns
durationButtons.selectButton(atIndex: 0)
durationBtns.delegate = self

//handle buttton tap
extension viewController: ButtonsViewDelegate {
    func didButtonTap(buttonView: ButtonsView, index: Int) {
        print(index.description)
    }
}

【讨论】:

    猜你喜欢
    • 2020-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多