In my custom drawn window I have a NSTextView under which I'd like to have NSScrollView separated by empty space. That's how I've set it up in xib.
In interface builder it looks fine, with nice space between the two of them
But when I run the program, the scroll view gets moves upwards, actually covering the text view:
But when I disable vertical autoresize of the scroll view, everything is working as it should.
text view and scroll view are under NSView so they are siblings to each other.
Most probably it was shortcoming of the system as the scroll view was being completely hidden and so then it was probably moved.
I've worked it out by subclassing NSScrollView and overriding
- (void)resizeWithOldSuperviewSize:(NSSize)oldSize_;
So now I can position the scroll view exactly as I wish.
Related
UIScrollview scroll is not working when i tested application in device (iPhone 5), But scroll is working properly in iPhone 5/5s/6/6 Plus simulator. I am developing application using Xcode 6 and UIStoryboard with AutoLayout.
I set the top, bottom, left and right constraints of UIScrollview with relative to Superview. And i also set the constraints of every UIControl which is in the UIScrollview.
Has any one have solution regarding this issue?
Please see below screenshot for reference.
It's probably easiest to have the scroll view contain a single view, which then contains all of your scrollable content. That single view should be anchored to all 4 sides of the scroll view, and if it's only meant to scroll vertically (which is what your screenshot makes it look like), then set the content view to be the same width as the parent of the scroll view.
To make sure an UIScrollView scroll, you have to check
Size
Your content View is bigger than your Scroll View. If you want it to be scrolled vertically, make sure its higher; horizontally, wider.
Constraints
Make sure your Scroll View is pinned to its super view, Top, Bottom, Leading, Trailing.
Make sure your Content view of Scroll View DOES NOT have CenterY constraint set to Scroll View, cause that'd make content view stuck with Scroll View and it'd never be able to scroll. (That happens to me the last time I was stuck)
Interface Builder settings
Make sure the check in Interface Builder under Scroll View is checked:
Scrolling section, Scrolling Enabled.
1) No table behind button
2) Table loaded
3) After scrolling
If I place a button over an NSTableView I get artifacts being left behind after scrolling. Does anyone know how to fix this?
My current solution is just to split the section with the table into 2. The lower portion is a disabled button in the background.
Try the NSScrollView method
- (void)addFloatingSubview:(NSView *)view forAxis:(NSEventGestureAxis)axis
All tableviews should normally be inside a ScrollView.
I had a similar problem and solved it, see Why does an NSTextField leave artifacts over an NSTableView when the table scrolls?. Essentially OSX will draw the contents of the table and let the parent scroll view move the cached contents avoiding redraws to be performant. By subclassing the parent scroll view it can be forced to refresh the table hooking the reflectScrolledClipView: method. Then the whole table, including overlays, will be redrawn with each scroll.
That's because the scroll view is set to copy its contents when scrolling and only redraw the newly-uncovered part as a performance optimization. To turn that off, use
myTableView.enclosingScrollView.contentView.copiesOnScroll = NO;
though that will make scrolling use more CPU (you can also do this in the XIB, look for a 'copies on scroll' checkbox).
Probably a better approach would be to switch the scroll view and the button to be layer-backed:
myTableView.enclosingScrollView.wantsLayer = YES;
myButtonView.wantsLayer = YES;
(Again, you can set this in the 'Layers' inspector of the XIB file, where you can click a checkbox next to each view to give it a layer) Now, the scroll view will only copy stuff from its own layer (which no longer includes your button). Also, now all the compositing of the text view will be done using in the graphics card. This works fine with an opaque push button, however, if you put text on a transparent background in its own layer (e.g. if you have a transparent pushbutton with a title), you lose sub-pixel anti-aliasing.
When I make an NSScrollView a subview of a layer-backed view (for example by choosing an NSTextView or NSTableView from IB), I see strange drawing behavior in the scroll view's document view.
To illustrate, I created a simple project with an NSTextView in a window. The only code I wrote is to turn on layer-backing for the window's content view:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[[self.window contentView] setWantsLayer:YES];
}
This is the result when I type into the textview. The red underlines don't line up properly:
http://mowglii.com/random/screenshot.png
Also, the text and underlines jitter a lot when I resize the textview. I've seen the same jitter on resize when I use a tableview (inside a scrollview) instead of a textview.
Any idea what is going on?
NSScrollView indeed misbehaves badly when embedded in a layer-backed view.
Some serious trickery is needed to animate views containing scroll views. You could try turning on layer-backing only once you need to animate. You then need to force the drawing in order not to end up with an empty layer.
Usually, you will however need to go look much deeper in the back of tricks. Namely: Keep layer-backing switched off. Draw the view into an image, display that image in an overlay view with layer-backing enabled. Animate that view to an image of the final state. Then remove the overlay view to reveal the actual final state below.
I'm trying to create a scrollable area in the middle of the screen - above it are a few non-scrolling labels, and below it are some non-scrolling buttons, so I only placed the UIScrollView in interface Builder in the middle of the window. I set the outline of the UIScrollView to be the full width of the iPad, 768 pixels, and about 700 pixels high.
I can place other UI elements within the UIScrollView as children of it, and I can scroll those by setting (in the view controller):
#define SCROLL_AREA_VERTICAL_HEIGHT 1200
...
[myScrollView setContentSize:CGSizeMake(768, SCROLL_AREA_VERTICAL_HEIGHT)];
[myScrollView setNeedsDisplay];
When I look at this in Interface builder, it seems to work, I can see only the UI elements that happen to fit with in the 700-pixel or so frame of the UIScrollView as set in Interface Builder. When I actually run it, though, I can see the UI elements that should be hidden below the lower boundary of the UIScrollView frame, and when I scroll up, the elements at the top don't become hidden by the top edge, but rather move up and over the labels on the top that are supposed to be static. In other words the boundary of the scroll area isn't actually hiding the elements that scroll off of it. What am I doing wrong?
Well i had a problem that was a bit like yours, don't know if it would work for you but try selecting the view in interface builder, and in the atributes inspector there is a box with a checkmark that sais clip subviews, check it and try. That was the solution for me. Hope it helps.
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).