ios - 是否可以通过编程方式将 "Button Shapes"覆盖为 Off?

标签 ios swift button

某些用户可能会将“按钮形状”开关设置为打开。 (设置 -> 辅助功能 -> 显示和文字大小 -> 按钮形状)

这会导致按钮标题自动带有下划线。在某些情况下这很糟糕,例如这个屏幕截图:

是否可以通过编程将其覆盖为“关闭”?我使用 Swift。

提前致谢。

最佳答案

这是一个使用 .setAttributedTitle() 删除 辅助功能 -> 按钮形状 应用的下划线的简单示例。

请注意,这只是快速拼凑在一起的——我还没有对其进行测试,所以不要将其视为“生产”代码。另请注意,代码非常“显示如何做到这一点”,而不是“这是一个好方法做到这一点”

class RoundButton: UIButton {
    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = bounds.height * 0.5
    }
}

class ButtonShapesViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor(red: 54.0 / 255.0, green: 15.0 / 255.0, blue: 30.0 / 255.0, alpha: 1.0)

        // just for easy layout / quick testing
        // add a vertical stackView holding two horizontal stackViews for two rows of buttons
        let svTopRow = UIStackView()
        svTopRow.axis = .horizontal
        svTopRow.alignment = .fill
        svTopRow.distribution = .fill
        svTopRow.spacing = 8
        svTopRow.translatesAutoresizingMaskIntoConstraints = false

        let svBotRow = UIStackView()
        svBotRow.axis = .horizontal
        svBotRow.alignment = .fill
        svBotRow.distribution = .fill
        svBotRow.spacing = 8
        svBotRow.translatesAutoresizingMaskIntoConstraints = false

        let svRows = UIStackView()
        svRows.axis = .vertical
        svRows.alignment = .fill
        svRows.distribution = .fill
        svRows.spacing = 8
        svRows.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(svRows)

        svRows.addArrangedSubview(svTopRow)
        svRows.addArrangedSubview(svBotRow)

        NSLayoutConstraint.activate([
            svRows.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            svRows.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        ])

        // fill "row" stackViews each with 4 buttons
        [svTopRow, svBotRow].forEach {

            sv in

            ["7", "8", "9", "÷"].forEach {

                title in

                let btn = RoundButton()
                btn.backgroundColor = UIColor(red: 201.0 / 255.0, green: 59.0 / 255.0, blue: 114.0 / 255.0, alpha: 1.0)
                btn.titleLabel?.font = UIFont.systemFont(ofSize: 28.0)
                btn.setTitleColor(.white, for: .normal)
                btn.setTitleColor(.lightGray, for: .highlighted)
                btn.setTitle(title, for: .normal)
                btn.widthAnchor.constraint(equalToConstant: 54.0).isActive = true
                btn.heightAnchor.constraint(equalTo: btn.widthAnchor).isActive = true

                sv.addArrangedSubview(btn)

            }

        }

        // now, let's disable the "Button Shapes" underlining for the bottom row

        svBotRow.arrangedSubviews.forEach {
            // just for sanity
            guard let btn = $0 as? UIButton, let title = btn.currentTitle, let curAttText = btn.titleLabel?.attributedText  else {
                fatalError("Not a button!")
            }
            // normal state
            let mutAttTextNorm = NSMutableAttributedString(attributedString: curAttText)
            mutAttTextNorm.addAttribute(NSAttributedString.Key.underlineStyle, value: 0, range: NSRange(location: 0, length: title.count))
            btn.setAttributedTitle(mutAttTextNorm, for: .normal)
            // highlighted state
            let mutAttTextHigh = NSMutableAttributedString(attributedString: curAttText)
            mutAttTextHigh.addAttribute(NSAttributedString.Key.underlineStyle, value: 0, range: NSRange(location: 0, length: title.count))
            mutAttTextHigh.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.lightGray, range: NSRange(location: 0, length: title.count))
            btn.setAttributedTitle(mutAttTextHigh, for: .highlighted)
        }

    }

}

结果(底行已禁用下划线):

enter image description here

关于是否实际执行此操作的哲学讨论超出了 Stack Overflow 的范围。正如您在评论中提到的,计算器按钮不显示下划线...日历应用程序“圆形日期按钮”、搜索按钮和“+”添加按钮也不显示下划线。


编辑

这是另一个示例 - 按钮的“5 x 5 网格”会根据设备旋转调整大小。

按钮点击只是将其标题附加到“inputLabel” - 不进行任何计算。除了“退格键”按钮外,它可以在“⌫”未选中状态和“⌦”选中状态之间切换。

class RoundButton: UIButton {
    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = bounds.height * 0.5
    }
}

struct CalcButton {
    var normalTitle: String = ""
    var selectedTitle: String = ""
    var foreColor: UIColor = .white
    var backColor: UIColor = .black
}

class ButtonShapesViewController: UIViewController {

    let inputLabel: UILabel = {
        let v = UILabel()
        v.textColor = .white
        v.textAlignment = .right
        v.text = "0"
        v.font = UIFont.systemFont(ofSize: 28.0)
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setContentHuggingPriority(.required, for: .vertical)
        v.setContentCompressionResistancePriority(.required, for: .vertical)
        return v
    }()

    var normAttributes: [NSAttributedString.Key: Any] = [:]
    var highAttributes: [NSAttributedString.Key: Any] = [:]

    let colorA: UIColor = UIColor(red: 254.0 / 255.0, green:  76.0 / 255.0, blue: 144.0 / 255.0, alpha: 1.0)
    let colorB: UIColor = UIColor(red: 201.0 / 255.0, green:  60.0 / 255.0, blue: 114.0 / 255.0, alpha: 1.0)
    let colorC: UIColor = UIColor(red: 196.0 / 255.0, green:  31.0 / 255.0, blue:  58.0 / 255.0, alpha: 1.0)
    let colorD: UIColor = UIColor(red: 255.0 / 255.0, green: 255.0 / 255.0, blue: 255.0 / 255.0, alpha: 1.0)

    let fColorA: UIColor = UIColor(red:  53.0 / 255.0, green:  15.0 / 255.0, blue:  30.0 / 255.0, alpha: 1.0)
    let fColorD: UIColor = UIColor(red: 197.0 / 255.0, green:  36.0 / 255.0, blue:  61.0 / 255.0, alpha: 1.0)

    var padButtons: [CalcButton] = [CalcButton]()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor(red: 54.0 / 255.0, green: 15.0 / 255.0, blue: 30.0 / 255.0, alpha: 1.0)

        padButtons = [
            CalcButton(normalTitle: "←",  selectedTitle: "", foreColor: fColorA, backColor: colorA),
            CalcButton(normalTitle: "→",  selectedTitle: "", foreColor: fColorA, backColor: colorA),
            CalcButton(normalTitle: "(",  selectedTitle: "", foreColor: fColorA, backColor: colorA),
            CalcButton(normalTitle: "()", selectedTitle: "", foreColor: fColorA, backColor: colorA),
            CalcButton(normalTitle: ")",  selectedTitle: "", foreColor: fColorA, backColor: colorA),

            CalcButton(normalTitle: "7",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "8",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "9",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "÷",  selectedTitle: "", foreColor: .white, backColor: colorC),
            CalcButton(normalTitle: "AC", selectedTitle: "", foreColor: fColorD, backColor: colorD),

            CalcButton(normalTitle: "4",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "5",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "6",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "x",  selectedTitle: "", foreColor: .white, backColor: colorC),
            CalcButton(normalTitle: "⌫",  selectedTitle: "⌦", foreColor: fColorD, backColor: colorD),

            CalcButton(normalTitle: "1",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "2",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "3",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "-",  selectedTitle: "", foreColor: .white, backColor: colorC),
            CalcButton(normalTitle: "↖︎↘︎", selectedTitle: "", foreColor: fColorD, backColor: colorD),

            CalcButton(normalTitle: "0",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: ".",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "π",  selectedTitle: "", foreColor: .white, backColor: colorB),
            CalcButton(normalTitle: "+",  selectedTitle: "", foreColor: .white, backColor: colorC),
            CalcButton(normalTitle: "✓",  selectedTitle: "", foreColor: fColorD, backColor: colorD),
        ]

        let svRows = UIStackView()
        svRows.axis = .vertical
        svRows.alignment = .fill
        svRows.distribution = .fillEqually
        svRows.spacing = 8
        svRows.translatesAutoresizingMaskIntoConstraints = false

        let font = UIFont.systemFont(ofSize: 28.0)

        var idx = 0

        for _ in 1...5 {

            let svRow = UIStackView()
            svRow.axis = .horizontal
            svRow.alignment = .fill
            svRow.distribution = .fillEqually
            svRow.spacing = 8
            svRow.translatesAutoresizingMaskIntoConstraints = false

            for _ in 1...5 {

                let cb: CalcButton = padButtons[idx]

                let btn = RoundButton()
                btn.backgroundColor = cb.backColor

                normAttributes = [
                    .foregroundColor : cb.foreColor,
                    .underlineStyle: 0,
                    .font : font,
                ]

                highAttributes = [
                    .foregroundColor : UIColor.lightGray,
                    .underlineStyle: 0,
                    .font : font,
                ]

                let attNorm = NSAttributedString(string: cb.normalTitle, attributes: normAttributes)
                let attHigh = NSAttributedString(string: cb.normalTitle, attributes: highAttributes)

                btn.setAttributedTitle(attNorm, for: .normal)
                btn.setAttributedTitle(attHigh, for: .highlighted)

                if cb.selectedTitle != "" {
                    let attSel = NSAttributedString(string: cb.selectedTitle, attributes: normAttributes)
                    btn.setAttributedTitle(attSel, for: .selected)
                }

                btn.heightAnchor.constraint(equalTo: btn.widthAnchor).isActive = true

                btn.addTarget(self, action: #selector(btnTapped(_:)), for: .touchUpInside)

                svRow.addArrangedSubview(btn)

                idx += 1
            }

            svRows.addArrangedSubview(svRow)

        }

        view.addSubview(inputLabel)
        view.addSubview(svRows)

        let g = view.safeAreaLayoutGuide

        let cLeading = svRows.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0)
        cLeading.priority = .defaultHigh

        NSLayoutConstraint.activate([

            inputLabel.topAnchor.constraint(greaterThanOrEqualTo: g.topAnchor, constant: 16.0),
            inputLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 16.0),
            inputLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),

            cLeading,

            svRows.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
            svRows.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -8.0),

            svRows.topAnchor.constraint(equalTo: inputLabel.bottomAnchor, constant: 16.0),

        ])

        // just so we can see the frame of the inputLabel
        inputLabel.backgroundColor = .gray

    }

    @objc func btnTapped(_ sender: Any?) -> Void {

        guard let btn = sender as? UIButton, let t = btn.currentAttributedTitle?.string, let curText = inputLabel.text else {
            return
        }

        if t == "⌫" || t == "⌦" {
            btn.isSelected = !btn.isSelected
        } else {
            inputLabel.text = curText + t
        }

    }

}

结果:

enter image description here

enter image description here

关于ios - 是否可以通过编程方式将 "Button Shapes"覆盖为 Off?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60563105/

相关文章:

iOS - 如何将 JSON 对象附加到 Web 请求? (不使用 NSURLConnection)

iphone - NSComparisonResult 和 NSComparator - 它们是什么?

ios - 返回 App 时 UIButton 动画停止?

ios - 类别中的 NSManagedObject 子类属性

ios - 如何以编程方式在父容器中制作两个相同大小的 UIView

c# - JS 中 C# var 的 asp.net 值

ios - 使 UIPickerView 结果导入文本到 UILabel

swift - 如何在 Swift 中提供带有错误类型的本地化描述?

ios - 约束重叠,Swift Xcode

c# - 更改数据 GridView 中图像按钮列中的图像