IKImageView and scroll bars - objective-c

I have an NSScrollView with an IKImageView inside to display images. This seems to work.
However, if I make the window smaller than the image, the scrollbars appear as they should, but the BOTTOM of the image is locked to the bottom of the window, instead of the top of the image being locked to the top of the window. In other words, I want the image to not move on the screen when I re-size the window from the bottom right.
I understand why this is, because in All of these classes, the origin is in the lower left, not the upper left. However, It's still behaving wrong. If you look at any other product (including Preview, which I assume is written with some of these libraries) the image/content/whatever, is locked to the top not the bottom.
How do I do this?
I've looked for methods in the NSScrollView and IKImageView. I've considered capturing the scroller events and manually moving the image down or up as appropriate, but I haven't seen a way to do this (Set the selector to a method I write in the controller?) and anyway, that seems very messy...
Is there an easy way to do this?
thanks.

Solution for future reference:
Make a subclass of IKImageView with only one over-ridden method:
-isFlipped()
{
return YES;
}
This subclass will also prove useful if I find that I need to re-implement the rotate:(id) method and the setImage:(NSImage) method which exist in the class (and in the case of rotate are USED IN THE DEMO supplied by Apple) but not documented, and therefore not officially supported...

Related

Is there a tutorial somewhere about designing a really large view and put it in scrollView using storyboard

The question may be similar with
Designing inside a scrollview in xcode 4.2 with storyboards
but none of the answer there makes sense at all.
Okay I created a new controller and I added a scrollView.
The very first thing I noticed is there is NOWHERE to specify the content size of the scrollView.
Not in attributes inspector, not in size inspector.
Then what?
I am expecting some larger than normal box where I can draw all the view I want to put in. There is no such thing either.
I am very frustated.
All the "tutorial" out there tell about how to fill scrollView using code.
Another thing I tried is to select controller go to size inspector and then choose FREEFORM.
Great. I still can't make that template big.
Should I do this in XIB instead? At least on that one I can have one huge UIView. Or what is the official way industry standard way of doing this? Is there a WWDC for this one?
Say I want to draw something like these:
I don't think you can get a tutorial on this as it is simply impossible in IB. As most people already commented out what you want to do here need to be done programmatically.
If you are using XIB you can set up all your content there. Under the size tab (in the inspector) you will need to change the height to fill all your content but you still need to set up your contentSize programmatically.
For storyboard I don't think it is possible to change the size of your scrollview in IB.

Force window to only resize on one edge - OSX Lion

As you know in 10.7 the windows can be resized by the user from all sides and corners. Is there any way to restrict the resizing of an NSWindow to only one side? Using setMinSize:and setMaxSize: won't do everything: by using those you can only restrain the resizing to two sides, not one.
To fix the cursor, track the mouse position use the mouseMoved event of an NSWindow subclass. When it is close to the top, call setMinSize = setMaxSize = whatever size the window is. When the mouse is closer to the bottom than the top, change the min size and max size back to whatever will let the user resize in the way you want them to.
Note that mouseMoved gets called whether the mouse is inside the window or outside of it (in my testing at least), as long as the window has focus. But for this to work, first implement -(BOOL) acceptsMouseMovedEvents { return YES; } in your NSWindow subclass.
As an extra safeguard, you can intercept and prevent any attempts at resizing using windowWillResize (not windowDidResize) in an NSWindowDelegate. From the Apple documentation:
-(NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
...
The frameSize contains the size (in screen coordinates) sender will be resized to. To resize to a different size, simply return the desired size from this method; to avoid resizing, return the current size. sender’s minimum and maximum size constraints have already been applied when this method is invoked.
Implement - (void)windowDidResize:(NSNotification *)notification and restore previously saved window frame if it was resized from the wrong side.
Window resizing behavior on any OS is really not your business. You either support window resizing or you dont. Its not your call to make how that happens except to support it or not. Users would prefer you do.
And as an addendum no theres no decent way to do what you seem to want...by design.

What is the best way to create a composite scrollable view on iOS

I need to create a scrollable composite view on iOS. That is to say, the view will contain at least one image, possibly a button, and some text (that we may wish to format with bold fonts, etc). The amount of data, and particularly the amount of text, is variable, from maybe 4 lines to maybe 100. The data is "variable" to a degree, and in particular the image and text do not come joined at the hip.
This all needs to fit in a "pane" of about 280h x 115w pixels in a portrait-only layout.
A single UITextView doesn't provide the facilities to display an image or format the text.
A UIWebView provides the ability to display the image and formatted text, but the button is a problem (not even sure if it's doable).
A UIScrollView would easily allow the image and button, and then a UIWebView could be embedded in the scroll view for the text, but then scrolling becomes a problem -- I'd like the entire view to scroll as one, without having to resize the web view to contain it's content, and without the confusion of a scrollable within a scrollable (the doc warns of "unexpected behavior").
(I'm guessing your thoughts at this point are that I want too much.)
So, any suggestions? What's the best way to get close to what I need here?
In iOS5 the UIWebView has a scrollView property, which is a normal UIScrollView. You should be able to add a UIButton as a subview of the scrollView to achieve what you want, although positioning it correctly may be a challenge. Prior to iOS5 you could cycle through the subviews of the UIWebView to find the UIScrollView with isKindOfClass...
I suggest testing with a UIWebView inside your UIScrollView. I don't see any interference in the iOS 5.0 simulator. I don't know if there are problems in iOS 4.0.
If you find that there is interference, you can prevent it by setting the web view's userInteractionEnabled property to NO, either in the nib or in code. This will prevent the web view from receiving any touches, so the user also won't be able to pinch-zoom it, follow links in it, or copy text from it.
In the web view's delegate, implement webViewDidFinishLoad: to set the web view's size and the scroll view's contentSize. For example:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
CGRect frame = self.webView.frame;
frame.size = [self.webView sizeThatFits:CGSizeMake(frame.size.width, HUGE_VALF)];
self.webView.frame = frame;
self.scrollView.contentSize = CGSizeMake(CGRectGetMaxX(frame), CGRectGetMaxY(frame));
}
When I did a similar thing, I had a dozen of views which I added to the UIScrollView and then calculated the frames of all the views. Granted, it was an extremely tedious work, given that some views could get hidden under various conditions. The layout code was actually pretty simple, laying out views from top to bottom, but ugly. The upshot is that it works like a charm, fast and reliably. You can even trivially wrap it in an animation block.

Resizing an NSView smaller than its subviews?

Couldn't find anything on the net about this and wondered if anyone on SO has a solution.
I have an NSView with several subviews that are centered by removing the left and right anchor points. When I resize my view, programatically or with the mouse, to a smaller width than the subviews: it pushes them off center. Has anyone come across this before and do you have a solution?
EDIT: I want to be able to resize my view to a zero width. The reason being, the view is actually part of a split view and I have hooked up a button to 'collapse' it. When it collapses all of the subviews are pushed off-center and aren't re-centered when the view is resized, effectively un-collapsing it.
I have solved my problem now and thought I would share incase anyone comes across this issue in the future.
No amount of playing with autosizing options or view layouts in Interface Builder seemed to stop my subviews from getting moved off center. I did manage to find this link here and from this page, the advice:
Springs and struts, as currently
implemented, are really no good for
anything but keeping either one or
both sides of a view "stuck" to the
nearest edge. Any sort of centering
behavior, division of gained/lost area
between multiple views, etc. has to be
done by hand.
Based on this I overrode my view's setFrame: method and manually laid out my subviews using their setFrame: method. This works great and gives me the results I'm looking for.
There is the same issue using NSSplitView, resizing here one Subview to be smaller than the Subview Subviews makes sense,e.g. having small charts in the upper subview, and an rss reader in the lower subview.
If you want to show only the rss reader in the lower subview, you can "hide" the upper subview, but after resizing the upper subview the NSImageView are not layed out the same as in the beginning. Check this nib/xCode Project and the following screenshot to see this behaviour.
Only workaroung is to override the resize function to stop getting smaller.

NSScrollView frame and flipped documentView

I have problems with NSScrollView, It is not displayed the way I want.
Yes I know there is a lot of post about it around the web, I need to override the isFlipped, in order to make it return YES, in my NSView subclass.
Ok, it's done, so now, my scrollView scroll from top to bottom, and not in the reverse way, as it was before overriding isFlipped.
But, this is the second part, my real problem, which I didn't found any answer on the web, how the hell I'm supposed to code, or create my view in interface builder, if everything is flipped? If I put something at the top, it is displayed a the bottom… do you have any magic trick to handle that?
And my last problem, is the NSScrollView frame. before setting the documentView of my scroll view, everything is fine, the scrollView is displayed at the place I choose, but, when I set the document view, it looks like the scrollview frame looks bigger, so I have to resize it…. is this a normal behavior?
Thank you very much.
The answer is usually to create an NSClipView subclass that returns YES from an override of isFlipped:
Then in IB, set the scroll view's content view (clip view) to your subclass.
Being flipped only applies its coordinate system to that exact view, not everything down the whole view hierarchy. So whatever you're putting directly into your flipped content view needs to be aware that it's flipped, but nothing else does.
And if you don't want it to work that way, just don't ask for it to be flipped! There's no rule that says that the document view of an NSScrollView has to be flipped, it's just very common for anything with variable-height content to be laid out top to bottom, which is easiest to do in a flipped view. If the layout you're doing works best as bottom-anchored, by all means, keep it unflipped, whatever's easiest. (And anything in Interface Builder should be fine anyway…did you actually see this problem, or are you just speculating that it might happen? I've never seen this issue…)
Setting the document view shouldn't change the size of the NSScrollView. You may have something else going on besides just that…