NSButton values are 1 - swift

I wanted to use an NSButton's integerValue to pass on information in a method and ran into a curious bug: whatever I set a value to - whether integerValue, stringValue, or floatValue, when I read it out, it's 1.
NSButton inherits from NSControl and should have the usual set of values... but all of them, including strings, resolve to 1.
Nothing I can see in NSControl.h or NSButton.h points to xxValue being anything other than ordinary properties.
I'm working in Xcode 9/Swift 4/macOS 10.12.6 - is this a known problem? Is this documented anywhere? I've used .tag as a workaround but would prefer not to.

It’s not a bug.
From the documentation of NSButton:
For most types of buttons, the value of the button matches its state—the value is 1 for on, 0 for off, or -1 for mixed. For pressure-sensitive buttons, the value of the button indicates pressure level instead.

Related

variable binding in a condition requires an initializer Swift GuideTour PlayGround error

I'm learning Swift, using this guide from the official website, in the form of PlayGround.
And I had this error:
I'm so confused... for one thing, this is an introduction guide, for another, I tried all of these and none of them work:
Luckily I finally got this one to work, but I don't know why...
So, I think my question is:
Why there's an error?
What's the original thought behind this part of guide design? I mean, what do they want to show us originally, knowing it's incorrect...
In my working code case, I don't see I can change my code to what's showing in the original guide example of if condition using optional variable. There's no way for this code:
if let nickname {
print("Hey, \(nickname)")
}
to work, right?
Answering your questions:
There's an error because the Xcode version that you are working with has a Swift version <5.7 (Xcode <14) which does not yet support if let shorthand syntax for optional binding when shadowing an existing optional variable (proposed in SE-0345).
For your second image, you are attempting to use optional binding with an non-optional string literal "something", which is, in semantics, pointless, not to mention being syntactically invalid.
The original idea behind this part of the guide is to familiarize you with the idea of dealing with optionals, specifically "optional binding", which is a technique used to work with optional values. You might wanna look into that via the official Swift language guide.
Short story: Think of variables as boxes. In Swift, these boxes can contain a certain type of data (e.g. String, Int, Bool, etc.). All these types that you might be already familiar with are solid data types that guarantee something of that type will be present in the box. But in some cases, you will be exposed to (or need) uncertainties in which you have no idea whether or not a solid piece of data is present within the box. This is when optional values come in--boxes that do not guarantee the presence of values (this box can either have something solid inside or nothing at all, nil).
Usually, we can force unwrap the optional values, but that can cause an error in your program when the box has nothing inside (Swift be like: hey! you promised me that there's gonna be a value inside the box but there's nothing inside, you untruthful creature! what do I do now? *rage halt*). That's why you need an optional binding: you tell Swift to carefully unwrap it and do something with the potential value inside (if it can be safely unwrapped) and do something else when there's nothing inside. The conventional syntax is:
if let aValue = anOptionalValue {
// if there's something inside the box, do something with it
print("haha found ya", aValue)
} else {
// otherwise do something else
print("oh no! empty box...")
}
Swift will now be happy: "at least you warned me that it might be empty inside and told me exactly how to handle it."
You are trying to use the shorthand syntax for optional binding which is only available after Swift 5.7 + Xcode 14. You'll need to get a Xcode 14 beta to use it.

NSTextStorage easily / background attribute change

I'm finishing a nice app with a relatively small text editor. During implementation of the syntax highlight I found myself in need to change foreground colour attribute of recognized tokens. I noticed that there is a property of NSTextStorage:
var fixesAttributesLazily: Bool { get }
The documentation, regarding it is:
A Boolean value indicating whether the text storage object fixes attributes lazily. (read-only)
Discussion
When subclassing, the default value of this property is NO, meaning that your subclass fixes attributes immediately when they are changed. The system’s concrete subclass overrides this property and sets it to YES.
I really don't know how to interpret this ... but this is what I did:
I'm changing the attributes of th recognised tokens inside textStorage(textStorage: NSTextStorage, didProcessEditing editedMask: NSTextStorageEditActions, range editedRange: NSRange, changeInLength delta: Int) (which is a delegate method of NSTextStorage). Here I'm checking the value of this property - it's FALSE.
I subclassed NSTextStorage exactly as Apple suggest (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextStorageLayer/Tasks/Subclassing.html) and overrode the property. The text view started to behave very strange. Actually with small text it performs OK, but as soon as I open a 4 Mbytes file - it hangs and ... well ... bad things start to happen to my mac. Actually this behaviour doesn't depend on the value of the fixesAttributesLazily property. Maybe my implementation of NSTextStorage is bad or at least not sophisticated.
Any trick of applying attributes in background or lazily or ... something like this is welcomed.
In additional: I know that there are many ways to optimise a syntax highlighted. It may highlight partially, use some kind of logic, based on the changed range ... etc. What I'm looking for is a way to process attribute changes in background. For example currently when I paste 4 Mbyte file to the text view, it first highlights it (which takes 2-3 seconds) and then it visualises it. The effect I'm looking for is the text to appear right away and after time - the colors.
The project I'm working on is written in Swift.
Thanks to everyone in advance for the help. You may reach me via ivailon at gmail dot com for specifics, since I don't want to expose the app here ... at least not yet ;-)

Swift SpriteKit GameplayKit check GKStateMachine does not equal state

I have just finished converting my game using the Entity and Component base architecture (GameplayKit) that apple introduced in iOS9.
I cannot figure out how to check that a current state (GKStateMachine) does not equal a state.
Say I want to check that the currentState is equal to my GameOverState, I would say this
if self.stateMachine.currentState is GameOverState {...
How would I check if the current state does not equal GameOverState, the "... is ..." sytanx is new to me so I am not sure how to call it.
I ran into this issue myself. It doesn't seem like ther is an inverse to is, so the only option I could see was to wrap the conditional statement to invert the boolean. So you would do like the following...
if !(self.stateMachine.currentState is GameOverState) {...
I found it hard to find documentation... so for yours, and others reference:
Documentation on the is operator (section titled "Type-Casting Operators")

Set cursor position in a UITextField (Monotouch)

In a UITextField used for entering decimal numbers I would like to get rid of possible leading zeros (The behavior should be like the one of the Calculator App). Normally this would be rather easy to implement but I just cannot figure out how to restore the cursor position.
UITextField has a property SelectedTextRange of type UITextRange which can be used to get the cursor position. However, there seems no easy way to get the current index nor to create a new UITextRange object that contains the new values.
I could find the solution in objective c: Finding the cursor position in a UITextField
It is however very unclear to me how to rewrite that in Monotouch. Any help with this would be highly appreciated.
Thanks,
Manuel
It looks like MonoTouch (at least the 5.3 alpha I'm looking now) is not exposing every methods in UITextField (and UITextView), in particular those that comes from UITextInput (but the properties are there).
This means that methods like GetPosition are presently missing - which makes it hard to duplicate the code from the link you provided.
UPDATE It was a bug where UITextInput methods were not added to UITextField and UITextView. This will be fixed in the next releases. IOW the next stable release, 5.2.11, will have the missing methods.

How to evaluate/watch a variable or method whilst debugging in XCode

I come from a Delphi and .Net background and have just started iPhone development. I just came across a problem whilst debugging.
I had the following code:
if ([displayText rangeOfString:#"."].location != NSNotFound) .....etc
I wanted to evaluate this whilst I was debugging but could not work out how to do it. I found the Expressions window and entered the below but nothing happened:
[displayText rangeOfString:#"."].location
As I'm used to Delphi & .Net (and I know XCode is a different product) its very easy to stick in variables, methods etc into a watch window and then see the result but I cannot see how to do this in XCode. Please can you tell me how I evaluate things whilst debugging??
Thanks
In your case, what you would do is at the debugger is type:
p (NSRange)[displayText rangeOfString:#"."]
You can print out the value of objects with po, but things like C structures have to be printed out with "p" and you have to cast the return types from ObjC calls to the correct struct type.
Also, just putting this in the Expressions window should result in a value:
(NSRange)[displayText rangeOfString:#"."]
In both cases you will see the whole NSRange struct, with location and length.
You can watch variables by going in the debugging drop down in the main menu on top and selecting watch variable. You can also right click and you should see the option "watch variable." Alternatively you can hover your mouse over the desired variable while stepping through your code to see its value at that time