Slider value not working for Accessibility - iOS8 - ios8

I have a slider and I want to limit its value to range from 1 to 5. I have set the min and max values on both Interface Builder and in codes but am currently facing two main issues.
1) The value doesn't change (keeps saying value 1).
2) On top of that, I am also unable to adjust the value of the slider when VoiceOver accessibility mode is on. The value keeps reading it as 1, even though on the surface, it may be on value 3/4/5.
Here are some of my codes to implement the slider in Swift. I am not sure what is the problem here with this. Any help is appreciated!
#IBOutlet weak var busSlider: UISlider!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
busSlider.minimumValue = 1
busSlider.maximumValue = 5
}
override func viewDidAppear(animated: Bool) {
busSlider.accessibilityValue = NSNumberFormatter.localizedStringFromNumber(busSlider.value, numberStyle: NSNumberFormatterStyle.DecimalStyle)
busSlider.accessibilityLabel = NSLocalizedString("\(Int(busSlider.value))", comment: "")
}
override func accessibilityIncrement() {
busSlider.value++
busSlider.sendActionsForControlEvents(UIControlEvents.ValueChanged)
busSlider.accessibilityValue = NSNumberFormatter.localizedStringFromNumber(busSlider.value, numberStyle: NSNumberFormatterStyle.DecimalStyle)
busSlider.accessibilityLabel = NSLocalizedString("\(Int(busSlider.value))", comment: "")
}
override func accessibilityDecrement() {
busSlider.value--
busSlider.sendActionsForControlEvents(UIControlEvents.ValueChanged)
busSlider.accessibilityValue = NSNumberFormatter.localizedStringFromNumber(busSlider.value, numberStyle: NSNumberFormatterStyle.DecimalStyle)
busSlider.accessibilityLabel = NSLocalizedString("\(Int(busSlider.value))", comment: "")
}
*On the side note: I actually have 2 sliders on the same screen but belonging to different sections. The first slider reads the value in percentage (speak rate), and this slider needs to read the value in integer (number of stops).

Related

Show/Move main window at custom position

Problem
I can't find function to set position of the window. I'v looked into code and I see SetPos func for different elements and wondering why it's not added for fyne.Window type.
func main() {
a := app.New()
w := a.NewWindow("Trying to position window")
if drv, ok := fyne.CurrentApp().Driver().(desktop.Driver); ok {
w = drv.CreateSplashWindow()
// something like this?
// w.SetPos(x, y)
// w.Move(x, y)
}
Workaround
I forked project and created func:
func (w *window) GLFWindow() *glfw.Window {
return w.view()
}
to expose unexported underlying window attribute w.viewport. and it unlocks bunch of methods i can use now
if ww := w.GLFWindow(); ww != nil {
ww.SetPos(x, y)
}
It looks I'm gonna use it (forked/edited version) but maybe you can suggest fyne-way to do it :)
Question
Is there existing way to set position of the window? Or access underlying w.viewport attribute?
This is not possible with the exported API, because many OS do not support it.
See discussion about the decision process at https://github.com/fyne-io/fyne/issues/1155

XCode 6 - Delay iterations in a loop?

I am testing a basic animation using a while loop. When the user touches a start button, an image randomly appears with every click of the button. I then placed the same code within a while loop and the image does not seem to move. I am thinking that it is just moving too fast through the iterations and therefore appears to not be moving. So, is there a way, simple or otherwise, that I can delay the speed of the loop so I can see a transition to some degree? I'm thinking that the speed of the loop is what is doing this, as text is instantly outputted to the label, thus I know the loop is working at least. Here is what I have...
#IBAction func btnStart(sender: AnyObject) {
isMoving = true
var i = 0
while (i != 200) //arbitrary number of iterations chosen for this example
{
var x = arc4random_uniform(400)
var y = arc4random_uniform(400)
myButton.center = CGPointMake(CGFloat(x), CGFloat(y));
++i
lblHitAmount.text = String(i) //200 appears instantaneously in label, loop is working
}
}
EDIT:
var timer = NSTimer()
var counter = 0
timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("tolabel"), userInfo: nil, repeats: true)
var i = 0
while (i != 800)
{
var x = arc4random_uniform(400)
var y = arc4random_uniform(400)
btnBug.center = CGPointMake(CGFloat(x), CGFloat(y));
++counter
++i
//lblHitAmount.text = String(i)
}
func tolabel(){
lblHitAmount.text = String(counter++)
}
So to understand why you are getting this behavior, you need to understand the idea of the run loop. Every app has a run loop that is essentially an infinite loop. Each iteration of the loop, it does a number of things. Two of the primary things are handling events (like tapping a button) and updating the GUI. The GUI is updated only once per run loop.
Your event handling code (for tapping btnStart), is run inside a single run loop iteration. No matter how long you delay your loop (say 10 minutes), the GUI will remain frozen until it finishes and then only display the last value the text was set to. This is why you get freezes in apps and programs. They have something running inside a single iteration of the run loop not allowing the execution to return to updating the GUI.
If you want to update the text periodically, you should look into NSTimer. You can setup a timer that repeats every X seconds and each time the timer is fired it will be executed in a different iteration of the run loop allowing the GUI to be updated with the intermediate values:
#IBAction func btnStart(sender: AnyObject) {
NSTimer.scheduleTimerWithTimeInterval(0.5, target: self, selector: "updateText:", userInfo: nil, repeats: false)
}
func updateText(timer: NSTimer) {
// do something to update lblHitAmount.text
// if you want to execute this again run:
NSTimer.scheduleTimerWithTimeInterval(0.5, target: self, selector: "updateText:", userInfo: nil, repeats: false)
// if you are done with the "loop" don't call scheduleTimerWithTimeInterval again.
}

error using < and >

hello I was making a simple guess the number game and suddenly I come up with
Cannot invoke '<' with an argument list of type '(#lvalue UITextField!, #lvalue UInt32)
this is my whole script
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var guess: UITextField!
#IBOutlet weak var text: UILabel!
#IBAction func button(sender: AnyObject) {
if guess > random {
println(text = "your number was too high. Try again")
}
if guess < random {
println(text = "your number was too low. Try again")
}
}
var random = arc4random()%100
...
thanks
You have to convert the string contained in the guess text field into an integer, by using the toInt() method, which returns an optional though, in case the string is not convertible to a valid integer.
I would use optional binding to do the conversion and assign a valid value to a variable:
#IBAction func button(sender: AnyObject) {
if let guessInt = guess.text.toInt() {
if guessInt > random {
println("your number was too high. Try again")
}
if guessInt < random {
println("your number was too low. Try again")
}
}
}
However that change alone doesn't work because toInt returns a Int, whereas arc4random returns a UInt - since swift doesn't have implicit conversion between data types, an explicit conversion to Int is needed:
var random = Int(arc4random()%100)
you've defined "guess" as a UITextField, which is certainly not the same type as "random".
You need to tell the compiler how to convert that to an integer.
Something like:
let guessInteger = guess.text.toInt()
and then:
if guessInteger > random {
println("\(guess.text) was too high. Try again")
}

Getting selected value of a UIPickerViewControl in Swift

How can I get the selected value of a UIPickerViewControl in Swift?
I tried something like this:
labelTest.text = Spinner1.selectedRowInComponent(0).description
But this only returns the selected index. I need the value.
Anyone who knows how to do this?
you will have to set the picker view delegate to self and override this function
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
// use the row to get the selected row from the picker view
// using the row extract the value from your datasource (array[row])
}
or
you can use this to extract as per your usage
var selectedValue = pickerViewContent[pickerView.selectedRowInComponent(0)]
where pickerViewContent is your array of dataSource
Swift 3: supose you want the String value of each row selected
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let valueSelected = yourDataSourceArray[row] as String
}
Swift 4
let selectedYearPicker = pickerData[yearPicker.selectedRow(inComponent:
print(selectedYearPicker)
Or
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let yearValueSelected = pickerData[row] as String
print(yearValueSelected)
}
All the answers so far presuppose you can easily connect the selected row back to the original data array. The solution is fairly easy if you can do that, but the question specifically addresses the case where the original array is not readily available. For instance I have 3 pickers in table cells that expand when one row is tapped, and they show 3 different arrays.
It would save me a lot of trouble if I could simply retrieve the selected text from the picker itself, perhaps in the code for my custom cell, instead of having to figure out which picker, which data array, which row and so on.
If the answer is that you can't, that's OK, I'll sort it all out. But the question is whether there's a shortcut.
The accepted answer is right except for it should include a typecast from String to Int:
var selectedValue = pickerViewContent[Int(pickerView.selectedRowInComponent(0))!]

How to get an enumeration's value's value?

In Apple's "A swift Tour" they have this code snippet:
enum OptionalValue<T> {
case None
case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)
How would you get the 100? You can't do possibleInteger == 100 to test if possibleInteger has the value 100 inside. I know you can put functions inside enumerations, but you can't have variables. Maybe I'm understanding enumerations wrong…
If I command click Optional when declaring an optional (var x:Optional<Int>), I can find
enum Optional<T> : Reflectable, NilLiteralConvertible {
case None
case Some(T)
init()
init(_ some: T)
/// Haskell's fmap, which was mis-named
func map<U>(f: (T) -> U) -> U?
func getMirror() -> MirrorType
static func convertFromNilLiteral() -> T?
}
But I do not understand what any of that means. Help?
You can use a switch statement to get the value, as described here. Relevant bit:
... the associated values can be extracted as part of the switch
statement. You extract each associated value as a constant (with the
let prefix) or a variable (with the var prefix) for use within the
switch case’s body:
For your case, you'd want something like:
switch possibleInteger {
case .Some(let value):
println(value)
case .None:
println("<None>")
}

Resources