How to detect the key press with keyDown on mac (objective-c) - objective-c

I am writing a keyDown in viewcontroller.m but it does not work.
This is my code:
-(BOOL)acceptsFirstResponder{
return YES;
}
-(void)keyDown:(NSEvent *)event{
NSLog(#"%hu",event.keyCode);
}

You always receive keyDown & mouseDown events in NSView class not in NSViewController class.
Create a subclass of NSView class, say it TestView and change default class of embedded NSView of NSViewController in Storyboard/Xib to TestView.
Also, it is always recommended to forward events to superclass especially one which you don't want to handle.
-(void)keyDown:(NSEvent *)event
{
NSLog(#"%hu",event.keyCode);
[super keyDown:event];
}

Related

Affecting UIViewController from a child UIView

My question might sound rather strange, but still I didn't find any reference and I really need help.
so my point is, I have a ViewController which has a collection of UIViews, to be specific a subclass of UIView with
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
overridden
from this event i want to load a specific data (according on the UIView touched) on the UIViewController's child UIWebView
Is there a way to address parent ViewControllers children from the UIView that receives the action
Or am I looking into a completely wrong direction.
Any hel will be greatly appreciated, thanks in advance.
You can use delegate for example:
#protocol someProtocol
- (void)recivedTouch:(UITouch *)touch fromUIView:(UIView *)uiView;
in you view:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
[self.delegate recivedTouch:touch fromUIView:self];
}
View controller implemed method from delegate:
- (void)recivedTouch:(UITouch *)touch fromUIView:(UIView *)uiView
{
if (uiView == self.someView)
{
// do some stuff with uiWebView
}
}
try to look at it differently. Your touchesBegan shouldn't do anything which is not connected with the view. Your view is just a UI component, it shouldn't control application flow (data loading). That's the job of the view controller.
Look how UIButton is implemented. The button does not do anything when clicked. The controller has to tell it "this is the method that should be called when the user clicks you"
There are two ways how to tell the view what it should do for a specific action - creating a delegate or passing a selector that should be called.
Consider also extending UIControl, which has most of the actions already implemented.
Alternatively use NSNotificationCenter: Send and receive messages through NSNotificationCenter in Objective-C?
Send a message from your view, hook the message from your controller. Notificationas can get a bit messy though, the delegate is probably a cleaner solution

event touchesForView: returns null in super view

I have a subclass of UIView called BigView that overrides touchesMoved (among other things) like so:
#implementation BigView
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet * viewTouches = [event touchesForView:self];
NSLog(#"set of touches: %#", viewTouches);
}
#end
My BigView instance also has a subview (regular UIView instance) - when I touch inside that subview, the above touchesMoved method gets called, but viewTouches comes up null. The subView doesn't override any of the event handling methods (touchesBegan, touchesMoved, etc). I would expect the touch count for a view to include all of the touches inside its subviews, but it doesn't seem to be working that way. Am I doing something wrong in the code, or is this the way it should work and I don't understand why? (If the latter, why is this better?)
Thank you!

touchesBegan ignored in subclass of uiresponder

working on an ios app with objective c and using xcode. I have a class that inherits from another class that inherits from UIResponder and it contains a view. I have a touchesBegan within the sub class but the event only gets called when running the app in debug/dev mode. when i make a production/release build the touch event is not getting called.
// Basic viewcontroller protocol
#protocol SubViewController
- (void)viewDidAppear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
- (void)viewWillAppear:(BOOL)animated;
- (void)viewWillDisappear:(BOOL)animated;
- (void)viewDidLoad;
-(UIView *)view;
#end
#interface SubViewController : UIResponder<SubViewController> {
}
/////////////////////////////////////////////////////////////////////////////////
// A custom subview controller
//
#interface mySubViewController : SubViewController {
}
and within mysubviewcontroller class i have
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//some code and magic
}
Now as i said running this in debug is fine but the touch event is ignored in release. any tips, ideas or questions to help clarify this for you please say. thanks in advance
edit: i seen this in the doc "If you override this method without calling super (a common use pattern), you must also override the other methods for handling touch events, if only as stub (empy) implementations." so i stubbed in all the other touch events but no change on release build
As you're not subclassing UIViewController (which does this automatically), you need to add your responder to the responder chain manually.
A UIViewController's position in the responder chain is between its view and the view's superview, so to get the same behavior, you need to override nextResponder in both your view and the controller that manages it. The view should return the controller and the controller should return the view's superview.

keyup keydown methods NSViewController

I made an instance of NSViewController and added it as a subview to the main window's content view. I want to be able to capture keyboard events, but I have no idea how to implement it.After some research, I learned I needed to implement acceptsFirstResponder and the keyUp:event: and keyDown:event: methods in the NSViewController, but after that I still don't have the thing working.
- (void)applicationDidFinishLaunching:(NSNotification*)aNotification {
/* GViewController subview of NSViewController */
GViewController *g = [[GViewController alloc] initWithNibName:#"GViewController" bundle:nil];
[contentView addSubview: g];
}
Those methods have to be present in a subclass of NSView, not NSViewController. It also doesn't make any sense to do addSubview:someViewController; the argument to that method needs to be a view.
override func keyDown(with event: NSEvent) {
super.keyDown(with: event)
Swift.print("Caught a key down: \(event.keyCode)!")
}
override keyDown with event worked for me in swift
you can try same method in object-c.
check out offical doc
https://developer.apple.com/documentation/appkit/nsresponder/1525805-keydown?language=objc

Capture Touch Event on UITableViewCell and after enter didSelectRowAdTindePath method

I want to personalize my UITableView changing background when user tap on a specific cell.
I've a dedicated ViewController for each cell and if I implement touchesBegan method in this viewController i can change my cell background without any problem. The problem is that the method "didSelectRowAtIndexPath" of the UITableView is no longer called. How can I call it manually? I am in another viewController and I have no access to that method. or how can propagate to the touch tableView?
Thanks a lot
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//do your operations
//send it to super class
[super touchesBegan:touch withEvent:event];
}
[super touchesBegan:touch withEvent:event];
Are you sending your action to super class? If not then add this line.