Storyboard editor layout confusion - objective-c

I am having layout problems with the storyboard editor with a fairly simple screen. I have a UIViewController to which I have added a 320x440 UIScrollView at 0,0 followed by a 320x20 UIProgressBar at 0,440. It looks fine in Storyboard editor. I'm not entirely sure how the 20 pixel status bar at the top of the screen is accommodated given the CGRect frame coordinates that Storyboard calculates.
On loading ( in -(void)viewDidLoad ), the UIScrollView frame seems to be set to 320x460 pixels at 0,0 but the UIProgressBar is still 320x20 at 0,440.
When I add subviews to the UIScrollView, (UIImageViews in particular), they get stretched and get clipped on the screen because although the UIScrollView thinks it is 460 pixels high, it only has 440 pixels of screen to display in.
Can anyone point me to a solution?
Thanks

OK - I have identified what was going on - there were a number of issues, nearly all to do with mutually incompatible settings in storyboard attributes on various view controllers.
In summary, the main view controller containing the UIScrollView had the 'wants full screen' checkbox ticked - goodness knows how, but it appears that I had then gone through other views trying to compensate for that initial error by clipping, resizing, setting layout constraints etc. which resulted in rather confusing outcomes.
My advice would be to not touch ANYTHING in storyboard editor unless you know what it's effect will be - it is a dangerous place. I found the issue by going back to basics and creating a trivially simple replication of my app and then observing the differences between that app and my own. Sorry if I wasted anybody's time researching an answer.
Thanks

Related

iOS 7 + Auto Layout: Strange UIImageView behaviour

I've got a strange UIImageView behaviour:
I've got a UIViewController with an embedded UIImageView and a close button. Very basic stuff, done a thousand times. I didn't use Auto Layout that much in the past, but another view controller in the same Storyboard has nearly the same config and doesn't appear as strange as this specific one.
In my Storyboard the Controller looks like that:
...and on the device it looks like that:
That image is 1024x768, so it should be filled to the bounds. Content mode in the image view is Aspect fill. When i dismiss the view, i can see that the upper part of the image view must be hidden at the top with some negative Y or something.
I need Auto Layout in this storyboard, because it's an iPhone + iPad App with both orientations.
Has someone hat a behaviour like that before?
Thank you!
Edit:
Here is the layout panel:
First, get rid of the alignment constraints, they are not needed if you're already anchoring your view to every side with a set distance.
Second, check the mode property of your UIImageView in the interface builder. If the image was not big enough and you had it set for "TOP" instead of, say, "aspect fill", you'd see something like this even though the view is actually covering the whole screen.
I'm sorry that I have to say this, but it was, as you certainly thought, my own fault.
The problem was that I made a photo with the iPad, and the iPad can be used in both orientations in this app. The photo was taken and was then used for an own view that allows the user to put annotations on the image.
The image gets then saved, and that was were the problem occured: I call
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0.0);
The landscape image was now taken into a portrait frame. After adjusting this and only allowing portrait mode, everything worked well.
Thanks anyways for your answers. And sorry for asking a question when the problem was another one and my own fault.

Mechanisms to move a view partly offscreen

I have a problem that nobody has yet offered any help with so let me ask a technical question to help me diagnose it on my own.
What mechanisms does the system have for moving a view so it appears to be partly off screen besides changing the view's frame (i.e. bounds/center) or transform?
This is an app which needs to run on iOS 5/6 still so I'm not using auto layout.
I have a fullscreen view reached via a push segue.
After a pause I hide the (translucent) status and navigation bars.
When the bars hide with animation they slide up off the screen.
In iOS 5/6 this just exposes the top of the view (which is an image). In iOS 7 it moves the entire view up "offscreen" a corresponding amount (i.e. 64 points if I hide both bars) showing a bar of content "below" the view at the bottom of the screen.
When I un-hide the bars (via a tap) the bars appear and the view moves back down to occupy the whole screen.
Whether the VC is set to extend the view under bars or not doesn't affect the behavior.
I have not been able to reproduce this behavior in a simplified app.
In either state, i.e. partly offscreen or fully onscreen, the top-level view frame remains {0, 0} 320 x 480 and the transform matrix remains {1, 0, 0, 1, 0, 0}. I have no idea what property of what object the system is changing to visually move the view. Perhaps if I knew what object/properties to examine I could deduce something about what is going on. Can anybody tell me how the system might be doing this?
The answer is that the "view" that was being moved was being presented by a UIPageViewController and I wasn't thinking about that. The UIPageViewController is presenting the child views inside a UIScrollView (subclass, I think) and so the scroll insets for the containing UIScrollView were being changed by iOS 7. Since the whole "presenting as a child" thing actually works -- of course I couldn't see the problem in the child view.
The "fix" was to un-check the View Controller setting for Adjust Scroll View Insets for the UIPageViewController view.

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.

Best approach for drawing a graph of almost infinite size in a UIScrollView on iPad

I'm currently working on an app which needs to draw s.th. like a network graph. Unfortunately this graph can become very big with thousands of movable objects.
I tried to put a giant UIView inside a UIScrollView but soon noticed this won't work because of memory limitations.
So I tried another approach: currently I have a UIView which has exactly the size of the visible part of the UIScrollView. The scrollview is set to not handle the scrolling (only the pinching). Instead I handle the scrolling in the UIView. Everytime a user scrolls, all graphic objects (those graphic objects are currently just subclasses of NSObject, which contain custom drawing code) are moved, so it seems like the view is scrolling. In the drawRect I only draw the graphics that are currently visible.
Also I constantly add and remove sublayers if they are moved out/in the visible frame
This works very smooth even with thousands of objects.
Unfortunately this approach has some drawbacks:
I can't zoom out to see all the objects in the graph, instead the user can only see a part of it
I don't get the inertial scrolling the UIScrollView offers
Other approaches I tried, like the CATiledLayer, don't work either because all the objects in the graph are draggable by the user and it looks really ugly if I use a CATiledLayer...
Swapping out the UIView with other UIViews while the user scrolls may help with the inertial scrolling, but it makes everything more complicated and zooming out completely still won't work :-(
Do you know of any best practices to draw graphs that can be very big?
//edit: I ended up with a uiscrollview which has a subview which has a cascrolllayer which has many sublayers. While zooming in and out the frame of the uiscrollviews subview is constantly changed to the uiscrollviews bounds by view.frame = scrollview.bounds. While dragging the scrollview the cascrolllayer is always forced to scroll to the current offset of the scrollview.
I needed to subclass the uiscrollview and hack around in order to make the zooming work nicely, but it's working well now. This approach works very well and allows very big graphs with lots of draggable elements.
//edit: see my other answer below, the approach above didn't work out as well as I initially thought, especially the zooming part
CATiledLayer is definitely what you should use here—there’s not really another solution that’ll let you use Quartz/UIKit drawing on a huge zoomable canvas. For anything that needs to be interactive (dragged or animated or whatever), you can disable its display in the main tiled layer and overlay another view or layer on top of it that just contains the object being interacted with.

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.