disabling UIButton throws an error - uibutton

I have two UIButtons, I want one button when pressed, to disable the other button.
I have tried code from different posters but have been unable to get one UIButton to disable the other UIButton.
I am able to setTitleColor and disable using Sender but that won't work for the other button.
Here is some partial code of the IF/Else statement, but it should be enough for the experienced coder.
This code builds successfully but throws an exception at the last line shown when run. Fatal Error: unexpectedly found nil while unwrapping an Optional value. Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_I...
import UIKit
import CoreData
class ViewController: UIViewController {
#IBOutlet weak var buttonAdd: UIButton!
#IBOutlet weak var buttonEdit: UIButton!
#IBAction func buttonAdd(_ sender: AnyObject)
{
if (sender.currentTitle == "Add")
{
sender.setTitle("Save", for:UIControlState.normal)
sender.setTitleColor(UIColor.red, for:UIControlState.normal)
buttonEdit.isEnabled = false FAILS ON THIS LINE

This generally happens when the outlet from your storyboard to your code is messed up. Go to storyboard, right click on the yellow ViewController symbol and you will see a warning. You should delete the entry with the warning by clicking on the 'x' and recreate a new outlet form storyboard to your code.

Related

Access on buttons in NSTableCellView

In my macOS XCode-project I addd a button to my Table Cell View which I want to access programmatically.
When I connect the button to an IBOutlet or IBAction I get following error message when I try to build my project:
/Users/homefolder/Desktop/myapp/myapp/Base.lproj/Main.storyboard: The myButton outlet from the ViewController to the NSButton is invalid. Outlets cannot be connected to repeating content.
Same for IBAction which is self-explaining.
Can you tell me how to access the button for each Table Cell View?
PS: Edit:
There is almost no code to show:
I added an IBOutlet in ViewController.swift:
#IBOutlet weak var remove_BTN: NSButtonCell!
Then I get the error as described above.
Same for the IBAction:
#IBAction func remove_BTN(_ sender: Any) {}

How to get characters from emoji picker [ctrl-command-space]

on OS X the 'Emoji & Symbols' picker can be started from the menu or [ctrl-command-space] how do I get the characters from this in my view? (just an NSView with text handling in core text).
i.e. I double click on the emoji in the picker and how do I receive it in my view - I'd guess there's a delegate I have to set somewhere - but can't seem to find the docs - I'm probably not calling it the right thing when I google
I've made a basic app
and added the lines below to the view controller
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.window?.makeFirstResponder(self.view)
self.view.becomeFirstResponder()
and made a view MyNSView with and set the view in the storyboard to MyNSView
override public func keyDown(with event: NSEvent) {
interpretKeyEvents([event])
}
When I use the emoji picker, the keydown doesn't fire (I put a breakpoint on it). Maybe the emoji comes from another method?
Seems I have to implement NSTextInputClient - see https://developer.apple.com/library/content/samplecode/TextInputView/Introduction/Intro.html
Seems I have to implement NSTextInputClient - see https://developer.apple.com/library/content/samplecode/TextInputView/Introduction/Intro.html

When segue is performing throws unrecognized selector sent to instance error message showed?

I've been looking for a solution since yesterday, and i still can't figure out actual problem.
My app has been worked for 2 months on ios8 devices. I also set it up for ios7 devices, but I didn't know it was crashing on ios7 devices because of segue.
This is prepareSegue function:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if (segue.identifier == "navigateToSettingsView") {
if let settingsView = segue.destinationViewController as? SettingControllerView
{
settingsView.isSetup = self.isSetup
}
}
}
My segue style is present modally and current context.
I have navigate function to perform segue like this:
func navigateToSettings() {
// call setting view for adjusting settings
dispatch_async(dispatch_get_main_queue(), {
self.performSegueWithIdentifier("navigateToSettingsView", sender: self)
})
}
I'm still tracing debug now, it's getting me annoyed so much. And in the debugger log area. The only prompt is 'containsString:' and unrecognized selector sent to instance. I know unrecognized selector issue, sorry for that. But my problem has no reason on debug log.Also, i can't use allocations instruments because of ios7.Eventhough, I'm not using any String contains function. I know the issue rangeOfString :S
[__NSCFString containsString:]: unrecognized selector sent to instance
I just ran into this issue as well, however my problem is in iOS 6.1 so it may be different. I didn't try to re-produce the issue in iOS 7 yet.
What I discovered was a newly added UITextField on my storyboard caused the crash. Removing the UITextField fixed the problem.
You may want to remove some recent UI elements from your storyboard and see if that helps. I found copying an existing UITextField and pasting it where I wanted the new one still allowed my app to run on iOS 6.1.

How to change value of the NSTextField instantly as we type?

There are two outlets connected to my ViewController.swift file.
#IBOutlet var myOutlet: NSTextField!
#IBOutlet var yourOutlet: NSTextField!
There is an action connected too.
#IBAction func myAction(sender: NSTextField) {
self.yourOutlet.doubleValue = myOutlet.doubleValue - 10
When i run the app, it works.
I enter 15 to text field that myOutlet connected, then hit the enter. And field that yourOutlet connected, takes the value of 5.
If there is no enter button needed, it would be better. So how to make the value change instantly, as we type?
Thanks for the answers.
I did not get a chance to do swift and OSX development, but I can lead you to the solution.
Take a look at textDidChange(_:)
Posts a notification that the text has changed and forwards this
message to the receiver’s cell if it responds.
Declaration
func textDidChange(_ aNotification: NSNotification)
Parameters aNotification The NSControlTextDidChangeNotification
notification that is posted to the default notification center.
Discussion This method causes the receiver’s delegate to receive a
controlTextDidChange: message. See the NSControl class specification
for more information on the text delegate method.
So to achieve your goal, you would implement this delegate, it will get called each time you edit the text inside of the NSTextField.Then inside of that delegate block you will provide the logic needed.

NSStoryboardSegue sample code (Yosemite Storyboard)

OS X Yosemite introduced NSStoryboardSegue
“A storyboard segue specifies a transition or containment relationship between two scenes in a storyboard…”
Update:
• If I attempt to use a NSStoryboardSegue subclass in a Storyboard with Yosemite., it crashes with SIGABRT.
• If I ignore segues, and manually present a view controller using a specified, custom animator for presentation and dismissal,
func presentViewController(_ viewController: NSViewController,
animator animator: NSViewControllerPresentationAnimator)
it works as expected.
This post provides additional insight: Animate custom presentation of ViewController in OS X Yosemite
Using that as a reference, here's my attempt so far:
class FadeSegue: NSStoryboardSegue {
override func perform() {
super.perform()
sourceController.presentViewController(destinationController as NSViewController,
animator: FadeTransitionAnimator())
}
}
class FadeTransitionAnimator: NSObject, NSViewControllerPresentationAnimator {
func animatePresentationOfViewController(toViewController: NSViewController, fromViewController: NSViewController) {
toViewController.view.wantsLayer = true
toViewController.view.layerContentsRedrawPolicy = .OnSetNeedsDisplay
toViewController.view.alphaValue = 0
fromViewController.view.addSubview(toViewController.view)
toViewController.view.frame = fromViewController.view.frame
NSAnimationContext.runAnimationGroup({ context in
context.duration = 2
toViewController.view.animator().alphaValue = 1
}, completionHandler: nil)
}
func animateDismissalOfViewController(viewController: NSViewController, fromViewController: NSViewController) {
viewController.view.wantsLayer = true
viewController.view.layerContentsRedrawPolicy = .OnSetNeedsDisplay
NSAnimationContext.runAnimationGroup({ (context) -> Void in
context.duration = 2
viewController.view.animator().alphaValue = 0
}, completionHandler: {
viewController.view.removeFromSuperview()
})
}
}
The problem appears to be with the Swift 'subclassing' of NSStoryboardSegue. If you implement the same functionality using Objective-C, everything works as expected. The problem is specifically with your FadeSeque class. The animator object works fine in either Objective-C or Swift.
So this:
class FadeSegue: NSStoryboardSegue {
override func perform() {
super.perform()
sourceController.presentViewController(destinationController as NSViewController,
animator: FadeTransitionAnimator())
}
}
Will work if provided as an Objective-C class:
#interface MyCustomSegue : NSStoryboardSegue
#end
#implementation FadeSegue
- (void)perform {
id animator = [[FadeTransitionAnimator alloc] init];
[self.sourceController presentViewController:self.destinationController
animator:animator];
}
#end
(I don't think you need to call super )
As this doesn't seem to be documented much anywhere, I have made a small project on github to demonstrate:
NSStoryboardSegue transitions from one NSViewController to another in the same Storyboard
NSViewController present: methods to achieve the same affect to a separate Xib-based NSViewController without using a Storyboard Segue
presentViewController:asPopoverRelativeToRect:ofView:preferredEdge:behavior:
presentViewControllerAsSheet:
presentViewControllerAsModalWindow:
presentViewController:animator:
animator and segue objects in Objective-C and Swift
edit
OK I've tracked down the EXC_BAD_ACCESS issue. Looking in the stack trace it seemed to have something to do with (Objective-C) NSString to (Swift) String conversion.
That made wonder about the identifier property of NSStoryboardSegue. This is used when setting up segues in the Storyboard, and is not so useful in Custom segues created in code. However, it turns out that if you set an identifier in the storyboard to any string value, even "", the crash disappears.
The identifier property is an NSString* in Objective-C
#property(readonly, copy) NSString *identifier
and an optional String in Swift:
var identifier: String? { get }
Note the read-only status. You can only set the identifier on initialising the object.
The designator initialiser for NSStoryboardSegue looks like this in Objective-C:
- (instancetype)initWithIdentifier:(NSString *)identifier
source:(id)sourceController
destination:(id)destinationController
and in Swift:
init(identifier identifier: String,
source sourceController: AnyObject,
destination destinationController: AnyObject)
Note the non-optional requirement in the Swift initialiser. Therein lies the problem and the crash. If you don't deliberately set an identifier in the storyboard, the Custom segue's designated initialiser will be called using a nil value for the identifier. Not a problem in Objective-C, but bad news for Swift.
The quick solution is to ensure you set an identifier string in Storyboard. For a more robust solution, it turns out that you can override the designated initialiser in your custom subclass to intercept a nil-valued string. Then you can fill it in with a default value before passing on to super's designated initialiser:
override init(identifier: String?,
source sourceController: AnyObject,
destination destinationController: AnyObject) {
var myIdentifier : String
if identifier == nil {
myIdentifier = ""
} else {
myIdentifier = identifier!
}
super.init(identifier: myIdentifier,
source: sourceController,
destination: destinationController)
}
I have updated the sample project to reflect this solution
The same issue comes to me since I forgot make Identity to the segue.
After that, my segue subclass could worked fine.
Highly recommend you take a look at the Apple documentation. If you dig into it a bit, you'll notice in the perform method, you can override animations and such:
SWIFT
func perform()
OBJECTIVE-C
- (void)perform
"You can override this method in your NSStoryboardSegue subclass to perform custom animation between the starting/containing controller and the ending/contained controller for a storyboard segue. Typically, you would use Core Animation to set up an animation from one set of views to the next. For more complex animations, you might take a snapshot image of the two view hierarchies and manipulate the images instead of the view objects.*
Regardless of how you perform the animation, you are responsible for installing the destination view controller o window controller (and its contained views) in the right place so that it can handle events. Typically, this entails calling one of the presentation methods in the NSViewController class."
What you might do as well is have a look at some of the iOS UIStoryboardSegue examples out there in the wild and you should find they're quite similar.