不为UISlider调用辅助功能增加和减少

时间:2019-05-06 00:48:23

标签: ios swift uislider

我正在尝试使我的应用程序更适合Voice Over用户使用。我有一个编号为1-100的滑块。如果启用了“ Voice Over”的用户向上或向下滑动以更改值,则将跳过多个数字。这意味着无法设置确切的数字。我正在遵循this网站上关于子类化UISlider并覆盖accessibilityIncrement()accessibilityDecrement()的建议,但是当滑块值更改时它们不会被调用。以下是我的子类别的滑块。知道为什么不调用这些方法吗?

class FontSizeSlider: UISlider {

  required init?(coder: NSCoder) {
    super.init(coder: coder)
    self.isAccessibilityElement = true
    self.accessibilityTraits.insert(.adjustable)
  }

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

  override func accessibilityIncrement() {
    self.value += 1
    self.sendActions(for: .valueChanged)
  }

  override func accessibilityDecrement() {
    self.value -= 1
    self.sendActions(for: .valueChanged)
  }
}

1 个答案:

答案 0 :(得分:1)

这是我上班时需要知道的事情,因此对我来说这是一个很棒的练习。感谢您发布问题。无论如何,我在Apple网站上浏览了this page后,就可以使用它。

我也无法调用增量/减量方法。我怀疑它们是步进特定的。 value属性OTOH被调用。

这是我想出的代码使其起作用:

class FontSizeSlider: UISlider {

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

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    func setup() {
        isAccessibilityElement = true
        accessibilityLabel = "Font Size Slider"
        accessibilityIdentifier = "fontSizeSlider"
        // accessibilityIdentifier = AccessibilityConstants.fontSizeSlider.rawValue

        minimumValue = 0
        maximumValue = 100
        isContinuous = true
    }

    override var accessibilityValue: String? {
        get {
            return sliderValueString
        }

        set {
            super.accessibilityValue = sliderValueString
        }
    }

    override var accessibilityTraits: UIAccessibilityTraits {
        get {
            return .adjustable
        }

        set {
            super.accessibilityTraits = newValue
        }
    }

    // Nobody needs to know about this outside the class, so marked it private
    private var sliderValueString: String {
        let stringValue = String(Int(value))

        return "The font size is \(stringValue)"
    }
}

您会注意到我使用了setup()方法,该方法对两个初始化程序都执行相同的操作。您可以根据自己的喜好调整最小值/最大值的值。

您会注意到我添加了accessibilityLabel,因此并不会忽略它是通用滑块。我也在那里添加了accessibilityIdentifier。可以将其用于UI测试,以便可以识别元素。

您可能希望将accessibilityIdentifier放在“所有人”都能看到的地方。也许是enumenum实现如下所示:

enum AccessibilityConstants: String {
    case fontSizeSlider
}

// Usage
accessibilityIdentifier = AccessibilityConstants.fontSizeSlider.rawValue

我使用自定义的设置器和获取器覆盖了accessibilityValue。另外,我为var更新时读取的字符串创建了一个计算的accessibilityValue。这是该部分的代码。请注意,我之所以这么做是private,因为班上没有人需要知道它:

// I adapted this from Apple's accessibility page that I posted above
override var accessibilityValue: String? {
    get {
        return sliderValueString
    }

    set {
        super.accessibilityValue = sliderValueString
    }
}


private var sliderValueString: String {

    let stringValue = String(Int(value))

    return "The font size is \(stringValue)"
}

最后一件事...除非在动画块或完成块之类的闭包内访问自定义self的属性,否则您无处不在UISlider

更新

已删除...

更新2

因此,假设您在viewController上,可以向滑块添加目标操作,如下所示:

    slider.addTarget(self, action: #selector(doSomething), for: .valueChanged)

@objc func doSomething() {
    print("How much wood could a wood chuck chuck if a wood chuck could chuck wood")
}

只要值改变,您的选择器就会被调用。