Display boolean as true/false instead of 1/0 in NSTableView - macos

In the implementation of theNSTableViewDataSource method
func tableView(tableView: NSTableView!, objectValueForTableColumn tableColumn: NSTableColumn!, row: Int) -> AnyObject!
, the returned result for a column is a native Swift Bool-typed value. I expected it being displayed as true or false in the table view. However, it is actually displayed as 1 or 0. I guess it might have been casted to AnyObject and became an Obj-C object. What's an easy way to make them displayed as true or false in the table view?

The Objective-C Bool type is actually an signed char under the covers.
objc.h:typedef signed char BOOL;
objc.h:#define YES ((BOOL)1)
objc.h:#define NO ((BOOL)0)
So when you return this as an object, you're actually returning something that gets cast to an NSInteger, which is why it's showing a 0 or 1.
To solve this, modify your object method to return
return theBoolValue ? #"true" : #"false"

Related

go generics: how to declare a type parameter compatible with another type parameter

I'm looking for a way to declare type compatibility between type parameters in Go generics constraints.
More specifically, I need to say some type T is compatible with another type U. For instance, T is a pointer to a struct that implements the interface U.
Below is a concrete example of what I want to accomplish:
NOTE: Please, do not answer with alternative ways to implement "array prepend". I've only used it as a concrete application of the problem I'm looking to solve. Focusing on the specific example digresses the conversation.
func Prepend[T any](array []T, values ...T) []T {
if len(values) < 1 { return array }
result := make([]T, len(values) + len(array))
copy(result, values)
copy(result[len(values):], array)
return result
}
The above function can be called to append elements of a given type T to an array of the same type, so the code below works just fine:
type Foo struct{ x int }
func (self *Foo) String() string { return fmt.Sprintf("foo#%d", self.x) }
func grow(array []*Foo) []*Foo {
return Prepend(array, &Foo{x: len(array)})
}
If the array type is different than the elements being added (say, an interface implemented by the elements' type), the code fails to compile (as expected) with type *Foo of &Foo{…} does not match inferred type Base for T:
type Base interface { fmt.Stringer }
type Foo struct{ x int }
func (self *Foo) String() string { return fmt.Sprintf("foo#%d", self.x) }
func grow(array []Base) []Base {
return Prepend(array, &Foo{x: len(array)})
}
The intuitive solution to that is to change the type parameters for Prepend so that array and values have different, but compatible types. That's the part I don't know how to express in Go.
For instance, the code below doesn't work (as expected) because the types of array and values are independent of each other. Similar code would work with C++ templates since the compatibility is validated after template instantiation (similar to duck typing). The Go compiler gives out the error invalid argument: arguments to copy result (variable of type []A) and values (variable of type []T) have different element types A and T:
func Prepend[A any, T any](array []A, values ...T) []A {
if len(values) < 1 { return array }
result := make([]A, len(values) + len(array))
copy(result, values)
copy(result[len(values):], array)
return result
}
I've tried making the type T compatible with A with the constraint ~A, but Go doesn't like a type parameter used as type of a constraint, giving out the error type in term ~A cannot be a type parameter:
func Prepend[A any, T ~A](array []A, values ...T) []A {
What's the proper way to declare this type compatibility as generics constraints without resorting to reflection?
This is a limitation of Go's type parameter inference, which is the system that tries to automatically insert type parameters in cases where you don't define them explicitly. Try adding in the type parameter explicitly, and you'll see that it works. For example:
// This works.
func grow(array []Base) []Base {
return Prepend[Base](array, &Foo{x: len(array)})
}
You can also try explicitly converting the *Foo value to a Base interface. For example:
// This works too.
func grow(array []Base) []Base {
return Prepend(array, Base(&Foo{x: len(array)}))
}
Explanation
First, you should bear in mind that the "proper" use of type parameters is to always include them explicitly. The option to omit the type parameter list is considered a "nice to have", but not intended to cover all use cases.
From the blog post An Introduction To Generics:
Type inference in practice
The exact details of how type inference works are complicated, but using it is not: type inference either succeeds or fails. If it succeeds, type arguments can be omitted, and calling generic functions looks no different than calling ordinary functions. If type inference fails, the compiler will give an error message, and in those cases we can just provide the necessary type arguments.
In adding type inference to the language we’ve tried to strike a balance between inference power and complexity. We want to ensure that when the compiler infers types, those types are never surprising. We’ve tried to be careful to err on the side of failing to infer a type rather than on the side of inferring the wrong type. We probably have not gotten it entirely right, and we may continue to refine it in future releases. The effect will be that more programs can be written without explicit type arguments. Programs that don’t need type arguments today won’t need them tomorrow either.
In other words, type inference may improve over time, but you should expect it to be limited.
In this case:
// This works.
func grow(array []*Foo) []*Foo {
return Prepend(array, &Foo{x: len(array)})
}
It is relatively simple for the compiler to match that the argument types of []*Foo and *Foo match the pattern []T and ...T by substitutingT = *Foo.
So why does the plain solution you gave first not work?
// Why does this not work?
func grow(array []Base) []Base {
return Prepend(array, &Foo{x: len(array)})
}
To make []Base and *Foo match the pattern []T and ...T, just substituting T = *Foo or T = Base provides no apparent match. You have to apply the rule that *Foo is assignable to the type Base to see that T = Base works. Apparently the inference system doesn't go the extra mile to try to figure that out, so it fails here.

Slider value not working for Accessibility - 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).

What exactly does .(data_type) method called/do?

I came a cross a piece of code that used .(string) method. Not knowing what this is called I had difficulties searching for it.
Here is my try to understand it:
package main
import "fmt"
import "reflect"
func main(){
var b interface{}
b = "silly"
fmt.Println(reflect.TypeOf(b.(string))) // we know that b
// is a string
// at compile time
fmt.Println(reflect.TypeOf(b)) // we do not
}
Result:
string
string
However, I think that reflect.TypeOf takes place at run time, while .(string) would tell the compiler that b is indeed a string, and this could be used to tell the compiler that a variable is of certain type. Is my understanding right?
goplayground
b.(string) is called a type assertion. As written in Effective Go:
A type assertion takes an interface value and extracts from it a value of the specified explicit type.
So, yes, the value you get from a type assertion is not an interface value, but is of the explicit type. You can also test if the type assertion was successful by adding an untyped boolean value:
s, ok := b.(string) // s is of type string
if !ok {
// b did not contain a value of type string!
}
Edit:
To explain further to clear out any possible misunderstanding:
A type assertion doesn't "tell Go that b is a string" as you suggested. What it does is that it will, in run time, try to extract a string from b, and panic if b contains some other type (unless assigning the optional bool value).
The value that you get from the assertion will indeed be of type string, allowing you to do things like slicing (you cannot slice an interface value) or checking its len.
The previous answer is correct. But I submit this as more like what happens in practice. The .(type) syntax is usually used with type names in the cases of a switch. In this example, I (integer expr), B (bool expr), and Bop (binary op) are type names.
func commute (e Expr) (r Expr, d bool) {
switch exp:= e.(type) {
case I: r,d = exp,false
case B: r,d = exp,false
case Bop: r,d = Bop{exp.op, exp.right, exp.left},true
default: r,d = e,false
}
return
}
This isn't unsafe like a C cast, because inside the case statement you are guaranteed to have the matching type. I see this quite a bit when reading a channel, where the type of the channel is an interface that all the cases implement.

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