Bottom UIToolbar off screen on iPhone 4 and 4S - ios

My problem is very similar to UIToolbar not displaying on iPhone 4 and iPhone 4s
I am using Xcode 7 and am trying to get a 'legacy' UINavigationController based iPhone app up and running on various iPhone screen sizes. By legacy , I mean it does not use Storyboards etc. The views are loaded from an .xib.
The app is a classic UINavigationController app with UITableViewControllers but with a UIToolBar at the bottom underneath the table view. The TableView and ToolBar are subviews of the view of the ViewController.
Works great on iPhone5/5s/6/6s.
But on the iPhone 4/4s the toolbar is off the screen. Oddly if I rotate the screen to landscape, the toolbar appears. Rotate back, it vanishes. I know this seems like prehistoric iOS code, but I am completely at a loss here and have wasted hours fiddling in Xcode and IB. I know I am missing something obvious.

It seems like the height of your table view is set to be a fixed height where the toolbar is visible beneath the table view on iPhone 5 and up. To get the toolbar to display on iPhone 4/4s requires reducing the height of the table view's frame using something like the following code.
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if (onIphone4 && portraitOrientation) {
CGFloat height = 480 - self.toolbar.frame.size.height;
self.tableView.frame = CGRectMake(0, 0, 320, height); // for iPhone 4/4s
} else if (onIphone5 && portraitOrientation) {
CGFloat height = 568 - self.toolbar.frame.size.height;
self.tableView.frame = CGRectMake(0, 0, 320, height); // for iPhone 5 and up
}
}
You will probably need to change the y position in the frame origin to account for the status bar and navigation bar if they are also present. In that case, the overall frame height will need to be adjusted for those changes. This is the frame-based way of adjusting view sizes.
The alternative and preferred method is to add auto layout constraints in the XIB for the toolbar and the table view in Interface Builder so that they will maintain the proper size and position relative to the screen dimensions.

I found the issue.. it was the "Full Screen at Launch" checkbox in IB, for the main "UIWindow"... and I quote from Apple documentation....
"If you choose to create a window in Interface Builder, be sure to select the Full Screen at Launch option in the Attributes inspector so that the window is sized appropriately for the current device."
Now please excuse me while I slam head against wall..way to waste a Sunday!

Related

UITableView Scroll Indicator in Left Side

I need to bring Scroll indicator to the left side of a table view.
self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, self.tableView.bounds.size.width-8);
Above code is working fine for iPhone 5, 5C etc.
But scroll indicator is not positioned well in iPhone 6. It shows some padding from left side.
In viewDidLoad method, the bounds of the view are not set correctly and if view is set in nib/storyboard, bounds are set accroding to size of view set there.
I guess, in your nib.storyboard you have chosen iPhone 5S/iPhone 5S size to design the view and henceit works in those devices.
If you set tableView's scrollIndicatorInsets in viewDidLayoutSubviews method, the indicator inset should set correctly.

Contents clipped using autolayout in 3.5 inch screen

i am using autolayout in my project. I added the contraints from the bottom to the top. Everything works fins in 4 inch screen . But screen is clipped when the project is run on 3.5 simulator.
Looking at the screenshots, it looks like there is no space to fit all your elements.
One way to go about it is, dock the elements at the top of the screen using the Top Space To Superview constraint, and dock the elements at the bottom using the Bottom Space To Superview constraint.
When you do this, if there's not enough space available, you'll probably see some of your subviews overlapping around the middle.
You can consider solving this by using a UIScrollView as a top level subview and add all your subviews to the scrollView. The content height of the scrollView will be calculated based on your constraints.
You can also manually set the contentView height after viewDidLayoutSubviews is called.
Personally I find that sometimes I can't seem to get Autolayout to work exactly as I want. So its worth putting a check in your viewDidLoad to manually move objects around a bit if the screen size is a 3.5 inch screen like so:
In my example I will be using a Button:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
CGSize result = [[UIScreen mainScreen] bounds].size;
if (result.height == 480) {
// 3.5 inch display
button.frame = CGRectOffset(button.frame, 0, 89.0f);
}
if (result.height >= 568) {
// 4 inch display
// .....
}
}

Resize UITableView for iPhone 5

How can I adapt an UITableView height to iPhone 4-inch screen? I have the following configuration, which works for iPhone 4. However on iPhone 5 (see image below) there is a blank space because the tableview does not rezise. The tableview is scrollable.
I've autolaout enabled and I tried defining horizontal and vertical spacing constraints for all views and the tableview, but I get the same results (see image below). Any suggestion?
This viewcontroller is placed inside a placeholder since I created a custom menu. I tried settting the constant of the placeholder in the parent view with the following code. Also not working, the tableview is clipped.
-(void) viewDidLoad{
if([[UIScreen mainScreen] bounds].size.height == 568) //iPhone 4inch
{
NSLog(#"iphone5");
self.dynamicTVHeight.constant = 465;
[self.placeholder needsUpdateConstraints];
}
else{
NSLog(#"iphone4");
self.dynamicTVHeight.constant = 375;
[self.placeholder needsUpdateConstraints];
}
And these are the constraints of my parentview, which implements a custom navigation menu. I did two tests:
With the vertical and horizontal spacing constraints:
And with the height constraint in my placeholder:
You need to set the bottomSpaceToContainer (or Bottom layout) to 0.
Make sure that there are no warnings or errors in your nib file (indicated by the yellow or red sign on your UITableView). If there are none, make sure you have all 4 constraints needed to fully describe your UITableView's position.
What you want :
To compare iphone 4 and iphone 5 :
Hope that will help =)

How to get a title to scroll above an iOS text view

I want to have a text title scroll above a text view, but can't find information on how to do it. I've been looking for days, but can't even figure out how to look for the info. I want the function to work like the Apple Notes app where the date text is positioned above the text entry location and scrolls off the screen with the text but is not editable.
I've tried placing labels above UITextView, but the label does not scroll with the textView. I have a sample Xcode project I'm work with, but not sure if it can be uploaded for others to see what I'm doing. I almost had success with the project, but the labels only scroll with the text in the landscape view, not the portrait view for some reason.
I've read Apple developer docs on TextViews and several other sources without finding any discussion on how to do this or examples to follow.
Can anyone point me in the right direction?
I'm sure there must be a better way to do this, but this is the only approach I've found to work after more than a week of trying to find a solution. If I can figure out how to upload the entire Xcode example project I will do that.
This is the explanation of the approach I found to work under iOS 6.1 and Xcode 4.5. I have only tired this on the iPhone 6.1 simulator.
After creating a full screen text view and placing a label at the top of the text view,
To get the label to scroll off screen with the editable text view you need to:
turn off autolayout in interface builder (uncheck Use Autolayout). (there appears to be a problem with autoLayout and scrollViews in iOS 6.x)
turn off the text view scrolling in interface builder (uncheck Scrolling Enabled)
set the text view content insets height (Top) to the label height
embed the text view and label in a scroll view.
set properties for the scroll view and text view to be able to access their properties
in viewDidAppear:animated:
a. set the scroll view content size height to 20 plus the greater of the screen view height or the text view content height plus the label height
b. set the text view delegate to self
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
float screenHeight = self.view.bounds.size.height;
// set the scroll view content height to 20 plus the greater of the view height or the text view content size height plus the label height
screenHeight = MAX(screenHeight, self.textView.contentSize.height + 20);
self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, 20 + screenHeight);
// set the text view delegate
self.textView.delegate = self;
}
set the text view height dynamically in textView delegate method textViewDidChange:
a. if the text view content height is greater than the view bounds height less the label height:
1. set the text view frame to the view bounds width and the text view content height plus the lable height
2. set the scroll view content height to the view bounds width and the text view bounds height plus the label height
// dynamically set the text view content size height
-(void) textViewDidChange:(UITextView *)textView {
if (self.textView.contentSize.height > self.view.bounds.size.height - 20) {
self.textView.frame = CGRectMake(0.0, 0.0, self.view.bounds.size.width, self.textView.contentSize.height + 20);
self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, self.textView.bounds.size.height + 20);
}
}
set the struts and springs in interface builder
1. set the scroll view and text view struts for left, right and bottom
2. set the scroll view and text view springs for width and height
3. set the label struts for left, right and top
4. set the label spring for width
The same settings need to be made every time the view changes orientations.
There might be a way to do this by setting constraints in code under autolayout, but I barely understand constraints, much less setting them successfully in code.
Hope this helps someone else.
What you are looking for is called UIScrollView. Take a look at the Apple documentation here.
A good tutorial on UIScrollView can be found on the Ray Wenderlich site.

Vertical centering view, autoresizing and iPhone 5 4" screen

I have some custom buttons I add to the view in -viewDidLoad. I want them centered vertically inside the view, like so:
self.customButton.center = CGPointMake(98.f, self.view.center.y);
However, the view height is 504.0 even on a 3.5" device, where I expect it to be 416 (480 - 20 (status bar height) - 44 (nav bar height)).
The view in xib is using "Retina 4 Fullscreen", but setting it to freeform does not help. I certainly don't want two xibs just to account for the height difference.
I know I can use UIScreen but I would prefer that the view be aware of the height difference.
EDIT: the odd thing is, in -viewWillAppear, view height is correctly set to 416.0. Why this isn't handled after [super viewDidLoad] is beyond me.
How are people handling this? Autolayout would probably handle this but I need a iOS5 compatible method. Can autoresizing handle "centering" somehow?
You don't have Autolayout in iOS5, but you do still have the autoresizing mask. If you center a view vertically in IB, go to the inspector and deselect the vertical struts and springs in the autolayout masks, the view will stay centered vertically on both 4" and 3.5" screens.
Or you can do this in code in your viewDidLoad method. Just center the view as you are now and set the autoresizingMask like this:
self.customButton.autoresizingMask = (UIViewAutoresizingFlexibleBottomMargin | \
UIViewAutoresizingFlexibleTopMargin);
EDIT: the odd thing is, in -viewWillAppear, view height is correctly set to 416.0. Why this isn't handled after [super viewDidLoad] is beyond me.
Because resizing the view is not part of loading the view! -viewDidLoad gets called from -view in a method that probably looks a bit like this:
-(UIView*)view
{
if (!_view)
{
[self loadView];
[self viewDidLoad];
}
return _view;
}
-(void)loadView
{
// Some code to load the view from a nib/storyboard...
}
The view will get resized with a call like yourViewController.view.frame = ..., but this can only happen after the view is loaded (and thus after -viewDidLoad is called).
Set some autoresizing masks. That's what they're there for.

Resources