scrolling NSTextView leaves scrollbar in wrong position - cocoa

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.

Related

Custom NSButton drawing messes up text rendering

I'm subclassing NSButton / NSButtonCell and everything works fine, but at least in Retina drawing as soon as I implement any of the drawing functions in either NSButton or NSButtonCell, the text rendering changes no matter whether I do some custom text drawing or delegate straight to the super implementation.
As you can see the text goes much thinner with just the anti-aliasing changing.
When I examine this in Xcode's Reveal-rip off, I see that the text is embedded in a NSButtonTextField when none of the drawing methods are overridden. As soon as any of the drawing methods are overridden, the NSButtonTextField disappears.
None of this happens when I insert a background layer behind the button text and set
button.isBorderd = false
but I don't much like that solution.
Is there any way of getting the same "fat" text rendering without messing with layers? Perhaps an attributed string attribute, a special text drawing command, anything?
Any help would be appreciated/
I wasn't able to reproduce your work-around with a background layer, though I might've been doing it wrong.
I ended up adding an NSTextField as a subview to the button, with the following attributes:
_titleTextField = [[NSTextField alloc] initWithFrame:NSZeroRect];
[_titleTextField setBordered:NO];
[_titleTextField setDrawsBackground:NO];
[_titleTextField setFont:[NSFont systemFontOfSize:13]];
[_titleTextField setTextColor:[FantasticalColors color:#"dimLabelTextColor"]];
[_titleTextField setStringValue:[self title]];
[_titleTextField setEditable:NO];
[_titleTextField setFocusRingType:NSFocusRingTypeNone];
[self addSubview:_titleTextField];
Then I was able to render all non-text in my cell's drawRect, and then let the text field render the text. Also not ideal, but was the only way I was able to match font rendering.
I have the same problem, not only in texts but in whole window. I solved it adding a new line in app Info.plist
High Resolution Capable Boolean YES
Show this Apple Tutorial
Before:
After:

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.

Subview not appearing where I want it to come out - Xcode

I'm new to XCode and am having trouble getting a subView, when added to the main view, to originate from the bottom whereas the top (which I presume is default).
When I mean top, I don't mean the heir-achy but rather literally top of the screen (where the power button and ear jack of an iphone is).
I have tried to play around with the View -> Origin, and View -> Mode - neither did anything.
I would assume it's the auto-layout but I can't be sure.
Basically, I have a colored mainStoryboard and it [self.view addSubView:[[AnotherView alloc] initWithNibName:#"AnotherView" bundle:nil]];
The AnotherView is just a empty half-sized View.
When it gets added, it keeps appearing from the top. I don't know how to make it come from the bottom.
Do you guys have any insight as to how I might be able to make it come from the bottom?
Thanks ahead of time!
add newView to self.view with the frame
newView.frame=CGRectMake(0,480,320,200);
and after that animate that view by using below animations.
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationTransitionCurlUp
animations:^{
newView.frame=CGRectMake(0,0,320,200);
} completion:nil];
Or you can use
presentModalViewController: animated:
method

Oomph MacMapKit Drawing Wrong

I've integrated Oomph MacMapKit in one of my projects, I did all the steps. But there is a problem.
I'm using a NSToolbar and switching between the views. whenever I'm in my map page if I switch into another page and then switch back to the map page, the map is drew under the MKMapView and MKMapView is white but I can navigate in map by dragging mouse in the white area.
I've tried it in another project as well, And it acts just like this again.
Normal Look
After switching back
Does anyone know how can I fix this?
This code is running in my window controller delegate for switching pages
- (NSView*)viewForTag:(int)tag
{
switch (tag)
{
case 0:
return [firstViewController view];
break;
case 1:
return [secondViewController view];
break;
default:
return [firstViewController view];
break;
}
}
- (IBAction)switchViews:(id)sender
{
NSView* currentView = [self viewForTag:[sender tag]];
NSView* previousView = [self viewForTag:currentViewTag];
currentViewTag = [sender tag];
[[[[self window] contentView] animator] replaceSubview:previousView with:currentView];
}
There is no special code in maps page.
Thanks in advance
I cannot fault your code. I presume you stepped through your code and checked that all views are properly added and removed. Also, you might want to check what frame is set for your map view after the switch. If the NSRect for the frame is where your white space is, somehow MKMapView is not keen on being added to and removed from the view stack.
It's a long shot, but you could try one of the following:
Use setHidden: to temporarily make your map view invisible, in stead of removing and adding it. Not sure, but you might gain a bit of performance from this as well as hiding and showing is probably less expensive than adding and removing...
Use addSubView: and removeFromSuperview to switch your views. This might need some code to provide for setting the framing of the views right or have a "default" frame handy that you can use when you add a view.
Bottom line MKMapView is wrapper around WebView, which sometimes seems to behave a bit odd.
This Map Kit is a bit buggy sometimes, changing my way of presenting views solved the problem.

NSTextView not refreshed properly on scrolling

I have a NSTextView with a sizeable quantity of text. Whenever I scroll however, the view isn't updated properly. There are some artifacts that remain at the top or the bottom of the view. It appears that the view doesn't refresh itself often enough. If I scroll very slowly the view updates correctly though. If I add a border to the view everything works perfectly, borderless view is the one that has a problem. Here's a link to a screenshot:
Thanks
Have you set the setDrawsBackground and copiesOnScroll propertes for either the NSScrollView or the NSClipView?
The first thing I would suggest is turning off the "draws background" property of the NSScrollView:
[myScrollView setDrawsBackground:NO];
Note that this should be set on the NSScrollView, and not on the embedded NSClipView.
The following excerpt from the documentation may be relevant:
If your NSScrollView encloses an NSClipView sending a setDrawsBackground: message with a parameter of NO to the NSScrollView has the added effect of sending the NSClipView a setCopiesOnScroll: message with a parameter of NO. The side effect of sending the setDrawsBackground: message directly to the NSClipView instead would be the appearance of “trails” (vestiges of previous drawing) in the document view as it is scrolled.
Looks like the text field isn't even in the scrolling-area... Are you sure something isnt overlapping it?
I had a similar trouble - artifacts develop when the NSTextView is embedded in another scrollview (ie. a NSTableView).
I actually turned on the setdrawsbackground, and then added a nice color to make it disappear again.
-(void)awakeFromNib{
NSScrollView *scroll = [self enclosingScrollView];
[scroll setBorderType:NSNoBorder];
[scroll setDrawsBackground:YES];
[scroll setBackgroundColor:[NSColor windowBackgroundColor]];
}
This in combination with a scrollWheel event let me use the NSTextView in a NSTableView.
-(void)scrollWheel:(NSEvent *)theEvent{
NSScrollView *scroll = [self enclosingScrollView];
[[scroll superview] scrollWheel:theEvent];
}
I had the same trouble some time ago. I don't remember how I solved it.
Try to place the NSTextView to another view if the superview is a custom view. Just to see what will happen.

Resources