Using UIScrollview in iphone5 compatible app - ios

I have a problem adapting my apps to the new iphone5 layout, I've made the following passes:
Added a retina 4" splash image
Modified the interface in my storyboard with "Size inspector" to change the anchoring of the widgets
Tested the app with iOS6 "retina 4" simulator.
The app works as expected except when the user pop up the keyboard to edit a text, I use the "stretching scrollview" method for this particular situation and this seems not compatibile with the "autosizing" properties of my widgets, here is an example, from iOS6 simulator, without and with keyboard:
And here is what happens:
I'm quite sure this is a coherent behaviour since my main view is stretched so the other items inside it are stretched following their anchoring, the fact is that I'd like to have the same behaviour of my previous fixed position (all widgets anchored to the top left corner) with the iphone5 gui expansion, is this possibile?
How do you solve the problem of showing a keyboard and scroll hidden content in an iphone 5 compatible way?

I have been having similar problems. From what I have found thus far, we may need to remove all constraints on the view within the scrollable view, because it appears that it's contents are being resized along with the frame of the scrollView. I know that setting the internal view's frame manually in viewWillAppear will work, but then you are stuck having a view that is the same size for both iPhone4 and iPhone5 (albeit it will scroll). Or you could "pin height and pin width" of the internalView right there in storyboard.
Two potential approaches that may work. Sorry I can't confirm these as I'm giving up and redesigning around this problem.
1. Programmatically add constraints to your internal view's subviews. The programmatic constraints will allow you to "spring" the distance between your elements proportionally. When adding constraints programmatically, you are given access to a factor called "multiplier" (not to be confused with priority), which I saw someone else on stackoverflow posting about.
2. You can design the internalView in Interface Builder as a separate viewController with it's .xib file, and then use storyboard to load it as an embedded viewController to a "containerView" object, which you would put in place as the new "internal view" of the scrollView. Perhaps then the .xib would first resize to the correct iOS device, and then you could use its frame to resize the containerView.
My advice is create a small test-case of these before implementing, else you end up like me, having spent hours down the wrong path and facing a dead-end.
UPDATE 12/4/12
Make your life easier by NOT setting the ScrollView as the main view of the ViewController.
--Instead, make ViewController.view a dummy/blank view, and embed a scrollView inside that view. Then, embed another view (my CustomView) in the ScrollView. CustomView contains all the visible controls and text boxes and buttons. There is NO HEIGHT CONSTRAINT on CustomView.

Related

How to scroll inside of UIScrollView in Xcode Storyboard Editor

I have a horizontally scrolling UIScrollView that runs "off" the screen. See image:
I want to be able to edit the content more directly in the Storyboard rather than guessing where to put Views etc. As you see in the image above, you can't see the entire text of the UILabel, nor the ImageView at the end, much less anything else I might want to put there.
I'm using Xcode 14.2.
I answered this ten years ago, and in a perhaps better way a few months after, but due to the endless vicissitude of Apple's designs, the procedure has become slightly different, so here's a new answer.
You can't scroll a scroll view in the storyboard editor. As a workaround, you can make the scene wider, and the scroll view wider, so that you can see all of its content in the storyboard editor.
Select the view controller in the storyboard outline.
Open the Size inspector. Change the setting for “Simulated Size” from “Fixed” to “Freeform”.
Increase the width of the simulated size as needed so that you can make your scroll view wide enough to see all its content. Depending on how your constraints (or autoresizing mask) are set up, the scroll view may get wider automatically.

How do I install and uninstall a UIButton based on size class?

I need a button to be installed in portrait orientation while another button is uninstalled in portrait orientation (any width, any height), while the reverse should occur in landscape orientation (any width, compact height). One of these buttons is part of a UIStackView and the other is part of a UIView.
When in portrait the button in the UIStackView should be installed, but the button inside the UIView should be uninstalled, with the reverse occurring as I mentioned earlier in landscape. Currently I'm checking the userInterfaceIdiom in my view controller for the storyboard, but would like to rely entirely on Interface Builder if possible.
When removing my code (that actually makes it behave correctly), and simply relying on Interface Builder for installing/uninstalling the buttons based on size class, the button installed for landscape orientation always lays out correctly, but when rotating back to portrait, the other button that should now be installed is completely misplaced, out of it's original UIStackView, and that UIStackView that it should stay in, but hasn't, is now expanded to fill in the missing space where that button should have been. When this is happening, there are no warnings or errors from UIKit in the log, and my storyboard shows no conflicts. I'm thoroughly stumped!
At first glance this seems like an easy solution. Simply check/uncheck the install box for size classes of a UI element. Although, even after reading Apple docs and tutorials this is proving to be more difficult and obscure than I expected.
To clarify, I do not have constraints set for the button installed for portrait orientation since it is inside a UIStackView. On the other hand, I do have a few constraints set for the landscape orientation button. Although, the button in the UIStackView is the only one giving me trouble.
The view debugger is not working either in Xcode 7, and I'm receiving the error: warning: could not load any Objective-C class information from the dyld shared cache. This will significantly reduce the quality of type information available. when attempting to use it.
I believe this may be a bug and related to this post: UIStackView properties according to size classes
Your help is greatly appreciated! Thanks.
If you want a component to appear just in a specific size class this is what you do:
Add the constraints to you component using the size class you want it to appear in (wCompact hRegular for all iPhone in portrait and wAny hCompact for all iPhones in landscape). Next make sure that only that size class is ticked in the Attribute Inspector.
Leaving Installed ticked will make the component appear in any size class. You can change the size class of a view controller in a storyboard file by clicking on the option in the center bottom of the screen (see the blue bar at the bottom of the screen, where it says wAny hCompact in the image above).
I hope this helps!
UPDATE
Make sure that the constraints of the components are also set for the correct size class.
From the Document Outline select the constraints of the component and check the size class of the constraint in the Size Inspector. Usually, when you add constraints to a component with a specific Size Class selected in the story board, the constraints will automatically be added for that size class.

How do I get a button to position on the bottom of a view controller in Xcode 7.2?

I used to be able to do this:
UIButton *bigBottomBtn=[[UIButton alloc]initWithFrame:CGRectMake(0, self.view.frame.size.height-60, self.view.frame.size.width, 60)];
I also used to be able to just drag a button onto a storyboard and add a constraint that would hold it to the bottom of the parent.
What is going on with Xcode, Autolayout and Apple for that matter....is my Xcode not working properly? Have I missed a major memo? is Apple just going downhill fast?
Your button-creating code used to work (and still does) if self.view's frame was correct at the time you created the button. Note that the view doesn't necessarily come out of the xib or storyboard with the correct frame; the xib/storyboard contains the view at some design size which might not match the current device. This wasn't as much of a problem when all iPhones had 3.5 inch screens, but became a pretty common problem with the advent of the iPhone 5's 4 inch screen.
The view isn't guaranteed to have its correct frame until its superview's layoutSubviews returns, so if for example you're creating bigBottomBtn in viewDidLoad, that's too early. Many questions on stackoverflow cover this problem. You either need to set the autoresizingMask of the button, or implement layoutSubviews or viewDidLayoutSubviews to update the button's frame, or turn off translatesAutoresizingMaskIntoConstraints and install constraints. Note too that your view can change size if you support rotation, slide over or split view multitasking, or if your view can be the detail view of a UISplitViewController, so it's a bad idea to try to guess the correct frame of the button based on the device's screen size at the moment the button is created.
Note that storyboards now by default use a design size of 600x600, which isn't the size of any device. This is probably because if Apple chose some device's size (say, the iPhone 5's 320x568) as the default, and you happened to use a device of that size as your primary (or only) test device, you could easily forget to think about what your app will look like at other sizes. However, you can explicitly set the design size to some device's size if you want:
I usually use “iPhone 3.5-inch” if I don't specifically need something bigger, because it lets me get the most scenes on the screen simultaneously (and produces the smallest screen shots for stackoverflow).
As for “I also used to be able to just drag a button onto a storyboard and add a constraint that would hold it to the bottom of the parent”, I have good news: you still can. Example:
However, you do need to be careful if you have filled your root view with a table view as appears to be the case in your screen shots. You need to drag the button to the document outline in that case, because if you drop it on the table view, Xcode will assume you want it to be the table view header:
Trying to pin a table view header to the bottom of the screen would be folly.
As for the Editor > Align menu, I have found that the items can be mysteriously inactive, which is frustrating.
Note, though, that only the “Horizontally in Container” and “Vertically in Container” will work (when they work at all) with a single view selected. To use the other items in the menu, you need to have at least two views selected, because the other items align the selected views with each other by setting their frames:
If you only have one view selected, Xcode doesn't know what other view you might want to align it to.
Those menu items are perhaps useful in the springs'n'struts model, but they don't add constraints, and under autolayout you probably want constraints to enforce the alignment at run time.
As far as I know, those menu items have never added constraints, but I'm not going to reinstall Xcode 6 to verify that, because there's a convenient popover that will add constraints corresponding to all of those menu items:
In xcode you always need to add buttons according to its visibility. As you said you need to show button on top of tableView and it should be aligned to bottom. For that You just need to arrange the order of items. as shown in the image below.Provide the layout for the button.

Change view sizes inside UIScrollView using Autolayout

I'm trying to create a 3x3 menu, based on a grid of buttons, and I'm facing a lot of problems trying to adapt it to different screen sizes.
Since I want my menu to be equally spaced on the screen (using autolayout tricks on the Storyboard), I have created a custom class with this menu that i'm adding to the center part of the main controller view. The problem is that the menu doesn't fit in small screen (3,5" screens).
Trying to solve this problem, I have created a scrollView in the main screen to add the menu and be able to scroll in small screens.
The problem is that since the view I'm loading in the scrollview, automatically fits to the size of the container (in this case the UIScrollView), only a small part of the menu is appearing in the 3,5" screen, without the option of scrolling (In bigger views it appears equally spaced and everything appears correctly).
How can I solve this UIScrollView problem? Or there is a better solution for this problem?
p.s: I'm sorry, but I don't have enough reputation to add images :(
Uiscrollview with autolayout has some pain into it.
You need to place you're inner views so the scrollview Will be able to understand the contentsize it should use.
You can find more detailed info here
http://infinite-edward.tumblr.com/post/66865604683/uiscrollview-contentsize-and-autolayout-gotcha

Designing inside a scrollview in xcode 4.2 with storyboards

I have a vertically scrolling uiscrollview - imagine an 'about this app' page of a tab bar app which goes on a bit and requires a scrollview. It only contains a few images, a video and some text (only the video has been coded in - the rest have been placed in the GUI). In storyboard (Interface Builder?) Xcode 4.2, everything is set up as it should be and works fine, but the view is only as large as what you see on the screen, is it not possible to manually arrange in storyboard the items that are initially offscreen - that you need to scroll up to? The only way I've found so far is to design them on the visible view then navigate them down with the arrow keys..
In the storyboard select the viewController, then in Attributes inspector change 'size' to 'freeform'. Then change the 'height' of the view/scroll view to as big as you need. The default settings of struts and springs should take care of resizing the view back correctly when the app is run, but you should double check.
I feel your pain. The only way I found is to manually pan the scroll view in the size inspector to reveal the portion of the view that you wish to visually edit.
Use a UIView to contain elements so they are positioned relatively to this view. Add the view as a subview to the scrollview at 0,0.
pan: use the Y coordinate say to -200, then edit the contents.
to place more contents in the hidden part, pan again to reveal new real-estate
when finished, restore the values of the ScrollView's height and X,Y position.
Make sure the scroll view frame rectangle is smaller than the contained view.
New: 3/26/2013
I stumbled upon what I think is even simpler way of dealing with UIScrollView directly in storyboard.
No code needed, just storyboard settings. This maybe new in iOS6.1 / Xcode 4.6
No need to disable constraints (i.e. uncheck "Use autolayout" in File Inspector for storyboard file)
No need to add UIScrollView* scrollView; in .h
No need to add self.scrollView.contentSize = ... in overrides of viewWillAppear or viewDidLoad
Here is what I did (important parts highlighted with **): (see code)
Create a new project with storyboard enabled
Drop in a UIScrollView, set class in identity inspector for view controller
In attributes Inspector, change Size under simulated metrics to Freeform**
Select scroll View; In attributes inspector, turn on "scroll enabled" and "background" to "White" (you'll figure out why - if you don't)
Under Size Inspector (with scroll view selected) change the height to 900 for example**
Add buttons, one on top and one at the bottom
Add a default handler for buttonTouchUpInside for both buttons and simply Log sender.
See Code Select the View Controller and scroll view and check inspectors.
Just change the 'Simulated Size' of the view controller to freeform and set a height that is larger than the usual size, you will be able to see all the outlets you need to edit.
On iOS 6.0 you can drag a Container View inside your Scroll View. This will automatically create a new View for your content, outside of the current scene. You can then resize this view as big as needed to fit your content.
I believe you would still have to set the ScrollView content height at runtime, but at least you can design you content view at once without having to scroll up and down on IB.
Just uncheck the "Autoresize subviews" from any view that you're trying to resize and it should keep all your objects from resizing with it.
I've been struggling with this for a while now, and every single thing I've tried has failed.
Specifically, What I am trying to achieve is a freeform sized modal dialog with a scrollable view containing a container for another view. I have had a lot of varied results, including occasionally having it working correctly. Most often I get it looking exactly correct, but with no scrolling.
In finally downloaded Dickey Singh's code, which worked perfectly but had nothing special. (Excellent clean solution BTW). So, I added a container view to it, exactly as I had in my code, and it broke!
After some experimenting, I worked out what is going on. Just bear with me.
1) Using Auto Layout, the size of the scroll view seems to dictate what the scrolling bounds will be. Setting "contentSize" in "USer Defined Runtime Attributes" seems to have no effect on this, and neither does setting "contentSize" or "bounds" in "viewWillDisplay" or "viewDidLoad". Thus if the initial size of the scroll view is 800x800, that will be all the space that can be displayed. For this reason, when I want a scrollable region, I create a container view and then put the scrolling view inside the content.
2) Without Auto Layout, setting "contentSize" in "User Defined Runtime Attributes" works, as does by setting it programmatically in "viewDidLoad". I prefer to use "User Defined Runtime Attributes" because it keeps the size with the layout. This solution allows you to use scrolling view with more flexibility, since it can be any size at design time.
3) Regardless of Auto Layout, if any view within the scrolling region exactly matches EITHER the horizontal or vertical frame bounds, then the scroll view ceases to function as a scroll view. This applies to my own code and to Dickey Singh's code in every possible configuration that I have tried.
I have no idea what is causing (3), but it is clearly a bug.
I hope this helps everybody out there who is struggling to use scroll view. I imagine that some people are using them without any problem, and some (like me) have had noting but problems with them.
Here's my solution to design a ScrollView with a content larger than the screen entirely in Storyboard (well, except for 1 single line of code :-) :
https://stackoverflow.com/a/19476991/1869369
I'm currently developing an app for iOS 7, and I did exactly as #Dickey Singh's answer, but it doesn't work in the beginning.
After checking the storyboard, I found that we also need to add Auto Layout Constraints for the view controller who holds the scrollView.
It seems that such auto layout constraints would be added automatically before Xcode 5, but now we need to do it ourselves.
The way to add constraints: First select the view controller in the storyboard; Enter 'Editor' in the top menu; Select the 'Resolve Auto Layout Issues'; Select the 'Add Missing Constraints In Container'. Done :-)

Resources