WebView cocoa doesn't respond to scrollWheel - cocoa

How to make it work? I added the override method in the class inheriting from WebView, but it doesn't get fired.
Any idea? Thanks in advance!
- (void)scrollWheel:(NSEvent *)theEvent

The WebView isn't the one catching the events; from what I remember, it's the frame view's document view that's getting the events, and it's often of class WebHTMLView, which is difficult to subclass.
[[[webView mainFrame] frameView] documentView]
I'm sorry but I don't know what to do to catch a scroll event in that case, maybe method swizzling or something of that sort. (though you can use something like -enclosingScrollView and set a custom scroller or something of that type)

Related

How to make a custom NSView within a NSMenuItem becomeFirstResponder?

I have a custom NSView within a NSMenuItem (attached to a MenuBar) that respond to a mouseDown event. But I need to click twice on the custom view for the mouseDown function to be called, this is because the custom view should be first responder. And when I override the method acceptsFirstResponder in my CustomView Controller as indicated by the Cocoa Event Handling Guide, it does not work. What is the solution? Is it doable?
Override the NSView method acceptsFirstMouse: to return YES for the event in question. If you only want to accept the first mouse click for some types of events, you can do that by examining the event parameter passed in. Unless there is something special about the NSMenuItem case in particular, this should be what you want; it's the standard Cocoa mechanism for this. Note that this method is not the same as the acceptsFirstResponder method you have tried. See Apple's doc for details.
For reference I have just added to my custom view the following:
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent {
return YES;
}

Click in view of NSCollectionViewItem

I'm new to Cocoa dev, so many concepts of it are not clear to me...
I'm trying to build a simple app which will use Flickr API to retrieve user photosets and show them in a NSCollectionView, by clicking them, will start to download the photos of the photo set.
I'm using Xcode 5.0.1 with latest SDK which is 10.9
After reading some articles about how to use binding to deal with NSCollectionView, I'm now facing another problem regarding handling events in NSCollectionViewItem.
Per I understanding, mouse events can be easily handled by implement
-(void) mouseDown:(NSEvent *)theEvent
In a NSView subclass, say
#interface MyViewController : NSView {
}
And assign the view custom class to the subclass I made (MyViewController) in InterfaceBuilder.
Now, I have no problem to do as above, and the mousedown did handled as expect in most of widgets.
The problem is, I have a NSCollectionViewItem subclass as below:
#interface MyItemController : NSCollectionViewItem {
}
I'm trying to implement mousedown method there, this class was set to as File's Owner in a separated nib file. And the view will be automatically load when the NSCollectionView loaded.
Now, MyItemController cannot be as customer class in the view object in IB which is obviously because of it is not a NSView subclass but a NSCollectionViewItem subclass.
If I write a subclass of NSView and make the custom class of view object, I can get the mousedown.
However, I cannot get the representedObject and index of NSMutableArray in this approach and they are the essential information I need.
So my question is, what is the right way to deal with mouse events view of NSCollectionViewItem?
My code in GitHub here:
https://github.com/jasonlu/flickerBackupTool
Thanks!
UPDATE
I found a approach to solve this problem is by subclassing NSView and implement mousedown and use super, subviews to get and index and the array itself
- (void)mouseDown:(NSEvent *)theEvent {
NSCollectionView *myCollectionView = (NSCollectionView *)[self superview];
NSInteger index = [[myCollectionView subviews] indexOfObject:self];
NSLog(#"collection view super view: %#",myCollectionView);
NSLog(#"collection index: %ld",index);
NSLog(#"array: %#", [[myCollectionView content] objectAtIndex:index]);
}
It seems work, but I'm not sue if this is the best practice, it looks like depends on view too much and took a long way to reach the array.
I wouldn't bet that NSCollectionView always creates all subviews (subviews which are far away from the viewing area might be delayed and/or reused). Therefore, I wouldn't rely upon subview searching.
Overload NSViewController to create an NSView so that the representedObject assigned to the NSViewController is accessible from the NSView. From there you could search the actual content for index determination.
Overloading NSCollectionView and recording the actual index during view creation would probably not work well because a deleted item probably doesNot re-create any views.

NSTableView Header Style

When an NSTableView has the style NSTableViewSelectionHighlightStyleRegular, the group rows have a very nice background and design overall.
I'd like a NSTableViewSelectionHighlightStyleSourceList Table view, but with the same header style.
Has anyone an idea how to do this, without having to subclass it?
I guess there is no other way then subclassing it, but it's pretty easy:
Just make a subclass of NSTableRowView, override the DrawRect method.
Check the property self.isGroupRowStyle. If it is, then write the code to draw it.
Else just call [super drawRect:dirtyRect];
In the TableView Delegate, return an instance in the
tableView:rowViewForRow: Method.
thanks anyway

cancelOperation not called in NSView subclass

cancelOperation: is not being called in my bare-bones NSView subclass when I press Esc.
I checked and the Esc key is received on keyDown. Also, other action messages (such as moveLeft) are being called.
The view is part of a Window shown like this:
[self.window addChildWindow:wc.window ordered:NSWindowAbove];
[wc.window makeKeyAndOrderFront:self];
What am I doing wrong?
In my case, I have an app with a couple of NSWindows. I had to call
[self.window makeFirstResponder:self] in my NSView subclass to have the view respond to cancelOperation:.
Are you implementing it as cancelOperation or cancelOperation:? There's a big difference. The method signature should be:
- (void)cancelOperation:(id)sender
This works for me with a vanilla NSView.
My derived NSView had the same problem. It was resolved after implementing acceptsFirstResponder as follows:
- (BOOL)acceptsFirstResponder
{
return YES;
}

Cocoa: setters in an NSViewController view

I'm using an NSViewController class with a single view in it to display a progress indicator bar and some text fields. I'm trying to use progressIndicator setMaxValue:and theTextField setStringValue: but neither of these are doing anything.
I've done this before and I've checked and rechecked, it's fairly straightforward, the fact that it's not working makes me think that it has to do with the fact that the class is NSViewController. Which is why I tried
Timers *aTimer = [[Timers alloc] init];
[aTimer.timerNameLabel setStringValue:#"name"];
[aTimer.progressIndicator setMaxValue:x];
in the app delegate which is an NSObject class, but that didn't work either.
I've tried looking around the NSViewController documentation but I can't find anything that says it can't set those values so I don't know what's happening. What am I doing wrong?
You probably want to use -initWithNibName:bundle: instead of a regular init to initialize your custom nib.
EDIT: It seemed the problem was due to the view not being queried before getting other objects. By calling [myController view] you actually load the nib, which isn't done automatically when you initialize the view controller. So before you can use any element of the view, you need to call [myController view]

Resources