cocoa: NSTextField with custom font, cursor out of wack - xcode

I have an NSTextField with a custom font set up in Interface Builder. When it loads, this is how it shows up:
When the user starts typing, the cursor moves correctly
And then when the user deletes the text it resets to the correct original position
Any ideas why this might be happening?

try to enable the CG layer for the textfield and its superview
.wantsLayer = YES;

Related

Extra Control inserted into Key View Loop in NSScrollView - Text View in Catalina

The default behavior for an NSScrollView - Text View in Catalina has changed. If the Text View has enough text to show a scroll bar, there is an extra control inserted into the Key View Loop after the NSScrollView has become firstResponder. Mojave does not show this extra control in the Key View Loop.
The 2nd control is a NSScroller contained in the Scroll View. NSScroller as firstResponder doesn't appear to have any functionality (e.g. arrow keys do not have any effect).
Can this behavior be turned off? Is there a way to make the ScrollView have a single responder in Catalina?
One thing I tried is setting "Refuses First Responder" of the NSScroller to false, but this had no effect.
Note: Full Keyboard Access (the Catalina equivalent) must be turned on to reproduce this.
I think the reason NSScroller accepts first responder is so that if all the subviews of your scroll view refuse first responder you still have a way to scroll the scroll view. While the NSScroller is first responder, if I hit page up/page down on my keyboard it scrolls the scroll view. If you want to disable this behavior you can:
scrollView.verticalScroller.refusesFirstResponder = YES;
scrollView.horizontalScroller.refusesFirstResponder = YES;

NSTableView displaying incorrectly in NSSplitView

I have an NStableView embedded in an NSSplitview.
The table will display, but when it does, the first three or so rows are not visible until I reize the window and/or split view. Then, it will snap into place and function perfectly fine until I quit.
Has this ever happened to anyone? Is there a simple method I can call on the view or table to get it to redraw?
This is how it displays when the view is first loaded (note: the user can scroll the table up and see the top row highlighted, but never get to it)
after resizing the window, the table view suddenly snaps into place and appears as it should:
You could try a [_yourSplitView display] to force a redraw of the NSSplitView. If I remeber correctly the SplitView will redraw all its subviews.
Try experimenting with where you use this, as result may vary depending on where in the init order you call this.
I actually got this working by calling the subview and then just resetting the position of the splitview divider.
NSView *v = [vc view];
[self.superDisplayView addSubview:v];
[self.SourceListSplitView setPosition:250 ofDividerAtIndex:0];

Cocoa: hide custom scroller of textview on application startup

I've created a custom scroller for my textview (initiating it in the awakeFromNib method of the scrollview) and now I want to let the user chose if he wants to show the scrollbar on application startup. The problem is that the scroller always appears even if I hide it immediately after I created it and set it to be the scroller of the scrollview. The weird thing is that trying to hide the scroller after an event has been triggered (for example by clicking on a checkbox in the preferences) the scroller properly hides and shows. What I'm I doing wrong? Any help is appreciated!
The weird thing is that before adding the custom scroller to the scrollview I have to use setHasVerticalScroller:YES, otherwise I can't scroll using the two-fingers scroll gesture. Then, if the user doesn't want the scrollbar to be shown I have to use setHasVerticalScroller:NO in the document's windowControllerDidLoadNib method, using it just after having added the scrollbar in the scrollview's awakeFromNib method won't work. Well, at least now it seems to work!
I've always used IB to set up scrollbars and then used the following line if I want to suppress one of them:
[self.aScrollView setHasHorizontalScroller:NO]; // so only the vertical scrollbar is active
Try using that line in awakeFromNib, later setting it to YES if user chooses, rather than using the "hidden" property.
P.S. An NSTextView added in IB is always embedded in an NSScrollView, and it's the scrollview that governs the scrollbars. So if the above doesn't work, try calling setHasWhateverScroller on the superview of your textview:
[[[aTextView superview] superview] setHasHorizontalScroller:NO];
If you get an "unrecognized selector" error, then try explicitly casting the superview to NSScrollView (which will work only if the superview really is an instance of NSScrollView):
[(NSScrollView *)[[aTextView superview] superview] setHasHorizontalScroller:NO];

How to change the height of an NSWindow titlebar?

I want to change the height of an NSWindow titlebar.
Here are some examples:
And…
I could use an NSToolbar, but the problem is that I can't place views very height (For example: I can't place the segmentedControl higher than in the picture because there is still the titlebar)
If I remove the titlebar I can't place a NSToolbar and the window isn't movable.
Have you any ideas?
This is much easier than one would think. I too went on a quest to do something similar for my app.
Real App Store app:
My App Store app look-alike:
No disrespect to INAppStoreWindow, it is a very good implementation and solid. The only draw back I saw from it though was that there was a lot of drawing code along with hardcoded settings for the TitleBar colors which Apple can adjust at anytime.
So here is how I did it:
A) Create a standard window with a Title Bar, Close, Minimize, Shadow, Resize, Full Screen - Primary Window all set.
Note: You do not need a textured window nor should you set a title
B) Next add a standard toolbar with these settings:
Icon Only
Visible at Launch - ON
Customizable - OFF
Separator - ON
Size - Regular
Remove all the Toolbar Items and add only these in the following order
NSSegmentControl (51 x 24) -- | Flexible Space | -- NSSearchField (150 x 25)
C) In your content View directly under the toolbar add a regular sized NSButton set like so:
Bordered - OFF
Transparent - OFF
Title -
Image -
Position - Text below the button
Font - System Small 11
Ok, pretty easy so far, right?!
In your Window Controller or app delegate....
setup IBOutlet(s) to your NSButton(s)
Note: Remember to hook up your IBOutlet in interface builder
Ok don't be scared we have to write a tiny bit of code now:
In awakeFromNib or windowDidLoad....
Get the content views' superview (aka NSThemeView)
Remove your button from its superView
Set the frame of your button
Add the button back to the theme view
So the code would look similar to this:
NSView *themeView = [self.contentView superview];
NSUInteger adj = 6;
[self.btnFeatured removeFromSuperview];
self.btnFeatured.frame = NSMakeRect( self.btnFeatured.frame.origin.x,
self.window.frame.size.height - self.btnFeatured.frame.size.height - adj,
self.btnFeatured.frame.size.width, self.btnFeatured.frame.size.height);
[themeView addSubview:self.btnFeatured];
That's it! You can use your outlet to enable/disable your button, setup a mask image when selected, enable/disable the toolbar or even hide everything and add a window title. All of this without worry if Apple changes their standard Window Titlebars.
P.S. No private frameworks were used in this posting whatsoever!
INAppStoreWindow is a NSWindow subclass, it tell you how to change the height of title bar.
https://github.com/indragiek/INAppStoreWindow
http://iloveco.de/adding-a-titlebar-accessory-view-to-a-window/
This example tells you how to add buttons in the title bar.
You'd have to subclass NSWindow and do a custom window frame drawing. It's not only about a titlebar. It's about whole window frame (so you can, actually, put close/minimize/zoom buttons at the bottom if you wish).
A good starter is at "Cocoa with love" website.
There are a few new solutions based on INAppStoreWindow and without warning and log message, for anyone who wants to change the height of NStitlebar, change the position of traffic light, add an item(e.g. a NSbutton) on NStitlebar and change its position, please check below.
WAYWindow:
https://github.com/weAreYeah/WAYWindow
NStitlebar_with_item:
https://github.com/ZHANGneuro/NStitlebar_with_item

NSTextView overlay causes oddities with first responder status

I have an NSTextView in an NSScrollView, and I am programmatically inserting an NSView subclass as a subview of the NSTextView. This NSView acts as an overlay, superimposing graphical information about the text beneath it.
I thought it was working quite well until I noticed that the text view does not respond to right clicks. Other operations (editing, selection) seem to work just fine.
Also, if the first responder is changed to a sibling of the scroll view (an outline view, for example) the text view does not regain first responder status from clicking on it. The selection will change in response to clicking, but the selection highlight is gray instead of blue (indicating that the text view is not the first responder).
If I offset the frame of the overlay subview, the text view behaves 100% normally in the area not overlapped by the overlay, but the overlapped area behaves incorrectly, as outlined above.
Steps To Replicate This Behavior on Mac OS X 10.6.4:
Create a plain old non-document-based Cocoa app.
Add an `NSTextView' IBOutlet to the app delegate .h.
Add an NSTextView to the window in MainMenu.xib. Connect the textView outlet.
Type in a bit of code:
In applicationDidFinishLaunching:
NSView *overlay = [[NSView alloc] initWithFrame:textView.bounds];
[textView addSubview:overlay];
[overlay release];
Run the app, observe that right click in the text area does not work as it should, yet you can still otherwise interact with the text view.
Next, add an NSOutlineView to the window in the xib. Observe that once focus leaves the text area (if you click on the outline view) with the overlay in place, you cannot set the focus back to the text view (it will not become first responder again).
Is there some way I can enable the NSTextView to receive all of its events, even though my NSView overlay does not accept first responder or mouse events? I suspect this might be related to the field editor – perhaps it is ignoring events it thinks are destined to the overlay view?
You probably need to make your overlay an instance of a custom view class that forwards all events and accessibility messages to the text view. You may also need to convert any view-relative coordinates to the text view's coordinate system.
I don't have a lot of experience with it, but another possibility would be to use a Core Animation layer as an overlay.
A clean way to handle this is by making your overlay view a custom subclass of NSView, and then overriding the hitTest: method to always return nil. This will prevent the overlay view from participating in the responder chain. Instead, events will get sent automatically to it's superview or views higher up the view hierarchy. You might also want to override acceptsFirstResponder to return NO to be safe (in case it's accidentally set programatically).

Resources