如何调整iOS选择器轮以生成随机索引

时间:2016-11-28 11:29:16

标签: ios swift swift3 uipickerview

使用XCode UI测试我们可以通过任何方式调整iOS选择器轮以生成索引值或获取索引值的文本并调整选择器轮。我能够使用下面的代码获取索引值。但无法获得指数值的值。

let picker = app.pickerWheels.element(boundBy: 1).otherElements.count
print(picker)
let randomNumber = arc4random_uniform((UInt32(picker)))
print(randomNumber)

使用拾取轮的计数我从中生成一个随机值。随着randomNumber的索引号我试图获取值。 有什么方法可以获得索引的值并将选择器轮调整到该值。

1 个答案:

答案 0 :(得分:0)

这就是我在XCTest UI测试框架中处理选择器的方法。

我有一个对象(PickerState),可以表示选取器轮的状态,使用选择器轮的值填充,其格式为"Some value, 4 of 5"getPickerState方法将值String转换为PickerState对象。

generateRandomNewPickerPosition为要移动的选择器生成一个随机索引,确保不会返回选择器的当前位置。

然后我在XCUIElement上使用扩展方法移动到changePickerSelection中随机生成的值。

/// Object to represent the state of a picker wheel.
class PickerState {
    let selectedValue: String
    let currentPosition: UInt
    let maximumPosition: UInt

    init(selectedValue: String, currentPosition: UInt, maximumPosition: UInt) {
        self.selectedValue = selectedValue
        self.currentPosition = currentPosition
        self.maximumPosition = maximumPosition
    }
}

/// Retrieve a PickerState object, given the value of a picker wheel.
func getPickerState(_ text: String) {
    // Separate value
    let splitText = text.componentsSeparatedByString(",")
    let selectedValue = splitText[0]

    // Extract numbers
    var numbers = splitText[1].componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
    numbers = numbers.filter { $0 != "" }
    let currentPosition = UInt(numbers[0])!
    let maximumPosition = UInt(numbers[1])!

    return PickerState(selectedValue: selectedValue, currentPosition: currentPosition, maximumPosition: maximumPosition)
}

/// Generate a new position (1-indexed) for the picker.
func generateRandomNewPickerPosition(pickerState: PickerState) -> UInt {
    let valueCount = pickerState.maximumPosition
    let random = UInt(arc4random_uniform(UInt32(valueCount - 1)))
    let newPosition = ((pickerState.currentPosition + random) % valueCount) + 1

    return newPosition
}

/// Move up/down the picker options until the given `selectionPosition` is reached.
func changePickerSelection(pickerWheel: XCUIElement, selectionPosition: UInt) {
    // Select the new value
    var valueSelected = false
    while !valueSelected {
        // Get the picker wheel's current position
        if let pickerValue = pickerWheel.value {
            let currentPosition = UInt(getPickerState(String(pickerValue)).currentPosition)
            switch currentPosition.compared(to: selectionPosition) {
            case .GreaterThan:
                pickerWheel.selectPreviousOption()
            case .LessThan:
                pickerWheel.selectNextOption()
            case .Equal:
                valueSelected = true
            }
        }
    }
}

/// Extend XCUIElement to contain methods for moving to the next/previous value of a picker.
extension XCUIElement {
    /// Scrolls a picker wheel up by one option.
    func selectNextOption() {
        let startCoord = self.coordinateWithNormalizedOffset(CGVector(dx: 0.5, dy: 0.5))
        let endCoord = startCoord.coordinateWithOffset(CGVector(dx: 0.0, dy: 30.0))
        endCoord.tap()
    }

    /// Scrolls a picker wheel down by one option.
    func selectPreviousOption() {
        let startCoord = self.coordinateWithNormalizedOffset(CGVector(dx: 0.5, dy: 0.5))
        let endCoord = startCoord.coordinateWithOffset(CGVector(dx: 0.0, dy: -30.0))
        endCoord.tap()
    }
}

let pickerWheel = app.pickerWheels.element(boundBy: 0)
let newPosition = generateRandomNewPickerPosition(getPickerState(pickerWheel.value))
changePickerSelection(pickerWheel, selectionPosition: newIndex)