NSWindow on second NSScreen OSX 10.13.4 or higher - xcode

NSWindow not placed on right frame in second screen.
With new OSX version I have the problem that I can set Frame but NSWindow will not set on correct screen. Only if I use setFrame animated works.
But it looks strange and cost performance. Somebody know what can help...
I try many things... but only animation bring window to the right NSScreen.
[fullScreenWindowPlaylist setFrame: screen.frame display:YES]; // not work
[fullScreenWindowPlaylist setFrame: screen.frame display:YES animate:YES]; // works
Greetings

Related

Magnify NSScrollView at cursor location

I have an NSScrollView with a custom NSImageView as its document view set up in the xib file. My problem comes when I want to magnify the NSScrollView. I would like it to behave like the Preview app on Mac, and I can get it to magnify just fine, but I want it to magnify with the cursor as the centered point.
I have this code in my custom NSScrollView class:
//Informs the receiver that the user has begun a pinch gesture.
- (void)magnifyWithEvent:(NSEvent *)event {
NSPoint conViewPoint =[[self contentView] convertPoint:[event locationInWindow] fromView:nil];
[self setMagnification:[event magnification]+[self magnification] centeredAtPoint:conViewPoint];
}
This works, however it also causes the scroll view to scroll down as it magnifies (though it doesn't move sideways at all). It's more noticeable when zooming in and out multiple times without lifting from the trackpad.
A similar problem seems to be in this question, however I'm using a pinch gesture and not buttons. I've been trying to offset the y axis scrolling as suggested for that question with
[[self documentView] scrollPoint:scrollPoint]
but I haven't been able to figure out a working formula for scrollPoint that accounts for the changing content view bounds to keep the point under the cursor in the same place. So, I'm wondering if there is a more proper approach to this or if the scrolling really is needed and I just need to figure out the math.
Thanks for any help with this
EDIT:
So I finally figured out the scrolling math. It took a while and way more complicated attempts, but is pretty simple in the end:
- (void)magnifyWithEvent:(NSEvent *)event {
NSPoint docViewPoint =[[self documentView] convertPoint:[event locationInWindow] fromView:nil];
NSPoint docRectOri=[self documentVisibleRect].origin;
float widthGapSize=-docRectOri.x;
float heightGapSize=-docRectOri.y;
if([event phase]==NSEventPhaseBegan){
startDocPoint=docViewPoint;
startPoint.x=(docViewPoint.x+widthGapSize)*[self magnification];
startPoint.y=(docViewPoint.y+heightGapSize)*[self magnification];
}
scrollPoint.x=startDocPoint.x-(startPoint.x/[self magnification]);
scrollPoint.y=startDocPoint.y-(startPoint.y/[self magnification]);
[self setMagnification:[event magnification]+[self magnification] centeredAtPoint:docViewPoint];
[[self documentView] scrollPoint:scrollPoint];
}
I still don't understand why setMagnification:centeredAtPoint: doesn't just work and am still wondering if anyone has some input on this as my workaround is very jittery on magnification because of the scrolling.

Panning problems with Cocoa NSScrollView

Im using Xcode to make an application that has a NSImageView that I have made into an NSScrollView (I think) by means of selecting it in my .xib, going to the editor menu in Xcode then embedded in > scrollView.
I have an image in my NSScrollView that is larger than the window it is opened in, I can scroll using the scroll bars fine and have even turned on the autoscroll: function in my mouseDragged: method.
I would like to be able to simply pan around the image without touching the edges of the screen using mouseDragged:. So far my code for mouseDragged: in my panning.m(subclass of NSImageView) is such:
-(void)mouseDragged:(NSEvent *)theEvent{
NSPoint p = [theEvent locationInWindow];
[self scrollRectToVisible:NSMakeRect(p.x - self.visibleRect.origin.x, p.y - self.visibleRect.origin.y, self.visibleRect.size.width, self.visibleRect.size.height)];
[self autoscroll:theEvent];
}
This works to some degree, however there is a lot of jittering. Maybe because I am not restricting the bounds?
I was wondering if I am on the right track or is there a better/more efficient way.
Any help is appreciated.
Cheers.

scrolling NSTextView leaves scrollbar in wrong position

I have an NSTextView inside an NSScrollView. I put text in the NSTextView and scroll it to the bottom programatically, which works OK, but the scrollbar stays at the top. Using the mouse to position the scrollbar causes it to jump to the bottom, where it belongs, and from that point it operates OK.
My code:
textView.string = s;
[textView scrollToEndOfDocument:self];
Don't get hung up on the scrollToEndOfDocument method--I also tried:
[textView scrollRangeToVisible:NSMakeRange(s.length, 0)];
and:
[[scrollViewText contentView] scrollToPoint:NSMakePoint(0, textView.frame.size.height)];
[scrollViewText reflectScrolledClipView:[scrollViewText contentView]];
with exactly the same problem, shown here:
I fixed the problem by adding one line:
textView.string = s;
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantPast]];
[textView scrollToEndOfDocument:self];
That runUntilDate call shouldn't be necessary. My theory is that it gives the NSScrollView a chance to catch up and synchronize itself, somehow.
This is all on Lion. I tried it with the System Preference set to both the Lion "backwards" scrolling and the the traditional pre-Lion scrolling, with identical results.
Any ideas about:
Why that call I added helped, and
How to make it work without that call?
Try NSScrollView's reflectScrolledClipView:
Edit: How about replacing
[[scrollViewText contentView] scrollToPoint:NSMakePoint(0, textView.frame.size.height)];
with
[scrollView.contentView scrollToPoint:NSMakePoint(0, scrollView.documentView.frame.size.height-scrollView.contentSize.height)];
Because as it stands I believe you're scrolling past the document view's frame.

How to customize / style a UIPopoverController

I'm working on an iPad application and I'm using UIPopoverControllers. I'm at the part where the app needs to be branded and styled and i'm wondering how to change the color / tint of the UIPopoverController? Standard is dark blue but it needs to be another color..
is this possible?
Greets, Thomas
This is possible starting in iOS 5.0 by subclassing the abstract class UIPopoverBackgroundView and assigning your subclass to the popoverBackgroundViewClass property on your UIPopoverController instance. Unfortunately there is no tintColor property as the popover needs to use images for it's arrow and border in order to achieve smooth animations during dynamic resizing. You can learn more about how to customize the appearance of a UIPopoverController in the UIPopoverBackgroundView Class Reference
It's impossible for now.
It's what I call the "Box in a Box" model. You get control of the box inside of the box (the UIViewController inside of the UIPopoverController), but you have very limited control over the actual popover itself. Outside of the arrow direction and the size, you can't change much else. There are also options for a modal effect popover, which dims everything else when it shows up, but I haven't tried to get it working.
I'm sure you've noticed there is no UIPopover class by now.
The answer you want to hear:
If you really want to style one that bad, just write your own. It's really not that hard.
The link you want to click:
Cocoacontrols is an index of iOS and OSX components available on GitHub, they have some popover stuff.
iOS 7 introduces backgroundColor property of UIPopoverController which affects/includes the navigation background color as well as arrows of popover.
#property (nonatomic, copy) UIColor *backgroundColor NS_AVAILABLE_IOS(7_0);
Usage example:
if ([self.popoverVC respondsToSelector:#selector(setBackgroundColor:)]) { // Check to avoid app crash prior to iOS 7
self.popoverVC.backgroundColor = [UIColor greenColor]; // [UIColor colorWithPatternImage:#"..."] doesn't reflect the color on simulator but on device it works!
}
Note - As of now (iOS 7.0.3), in some cases (like set color using colorWithPatternImage:), the simulator (and even some devices) doesn't honor the color.
Throwing my hat in here;
I've leveraged UIPopoverBackgroundViews in iOS 5+ to add a simple tintColor property onto UIPopoverControllers.
PCPopoverController: https://github.com/pcperini/PCPopoverController
I try to trick it by customizing the view controller inside the popover and then hiding the popover border using this code:
UIView * border = [[insideViewController.view.superview.superview.superview subviews] objectAtIndex:0];
border.hidden = YES;
The app is actually still in development so I'm hoping other people will comment on this solution.
check out these latest projects leveraging UIPopoverBackgroundView
https://github.com/CRedit360/C360PopoverBackgroundView
https://github.com/GiK/GIKPopoverBackgroundView
from ios 5 onward it is can be done, here is a library
https://github.com/ddebin/DDPopoverBackgroundView
just look at the documentation , and it is quite easy
good luck
You can use Elegant Popover cocoapod for just that. You can customise shape and colour of the arrow and the popover itself. Also, you can add colourful borders to the popover.
I know this is a lousy constructed answer, but I've just been playing with the UIPopoverController's views. They do exist.
The only way to access them is from your view that is sitting in the UIPopovercontroller.
I have a navigation controller so I follow this hierarchy
UIView *test = ((UIView *)[[[self.navigationController.view.superview.superview.subviews objectAtIndex:0] subviews] objectAtIndex:1]);
UIView *test2 = ((UIView *)[[[self.navigationController.view.superview.superview.subviews objectAtIndex:0] subviews] objectAtIndex:1]);
test.backgroundColor = [UIColor greenColor];
test2.backgroundColor = [UIColor greenColor];
This isn't exactly the end goal, but it is really close.
you'll find that the_view_in_the_popover.superview.superview (maybe just one superview if you are not reaching out from a navigation controller view) is a UIPopoverView. If you cast it as a UIView and treat it as a UIView you're not really breaking any rules. I guess that is really up to apple though.
Remove UIPopoverController border:
NSArray* subviews = ((UIView*)[popupController.contentViewController.view.superview.superview.superview.subviews objectAtIndex:0]).subviews;
for(UIView *subview in subviews){
[subview removeFromSuperview];
}

Centering Windows on screen

Short and sweet: How can I tell Interface Builder to center a window on a user's screen? I've seen the positioning tool on the inspector, but eyeballing doesn't always land as squarely as I like. Is this something where I should switch over to Xcode and add something to the init or awakeFromNib methods?
You could use [window center] as answered by wahkiz, but that might not be exactly what you want. The documentation states that this will put the window centered horizontally, but somewhat above the vertical centre. In this way the window has a visual prominence.
If you want to put your window in the exact centre, then manual positioning (as commented by Koning Baard XIV) will work for you.
Use [window center]; for the centre of the window to be centred to the screen.
Also, assuming you're in 10.5+, there is a centre to screen button in Interface Builder.
In your appdelegate, in applicationfinishedlaunching, add this code at the bottom.
[window center];
For macOS Mojave this worked for me, in AppDelegate applicationDidFinishLaunching for the Main Window:
[[[NSApplication sharedApplication] mainWindow] center];

Resources