EDIT: This is not an issue with the frame. The frame is in the correct spot. It is the content that is off. Yes, we are compensating for clear status bar. ViewDidLoad shows content offset is at 0,0.
On every page of my applcation that has a scrollview it's content is pushed down by 20 pixels. I think it may have something to do with the new StatusBar, or lack thereof. The bug also seems to be present in the simulators settings menu. Screenshot below. This only seems to affect the first scroll view that is added to a ViewController and only if no other views have been added to it. Table views are also being affected because they inherit from Scroll view. To be clear the scrollview starts at the correct origin but the content is pushed down by 20 pixels. This is bizarre because I would think if it was a status bar issue it would be 20 pixels above not below.
Currently we are fixing it by adding this to our base view controller
UIView *hackView = [[UIView alloc] init];
hackView.frame = CGRectMake(0, 0, 0, 0);
[self.view addSubview:hackView];
Obviously, this is a hack.
The same thing is happening on phone and in simulator even with the Gold Member version of IOS7 when building for latest IOS7. You can even see an example of the bug in the simulator's settings tableview and also in ours below.
This is a screenshot immediately after it loads. One bizarre thing that we noticed is that when we execute a pull to refresh it will correct the scrollview and rest at it's correct location. Alternatively, if we compensate it will look correct in the beginning but any subsequent pull to refreshes will migrate the scrollview to -20px
After further testing in Xcode, my original workaround still works, but the real culprit seems to be a Navigation Controller combined with the Adjust Scroll View Insets flag on the view controller. Disabling that solved the issue.
[self setAutomaticallyAdjustsScrollViewInsets:NO];
Original workaround: Try reordering your view hierarchy or add an empty view at the top.
This happened to me, and it appears that when a UIScrollView or similar subclass is first in the hierarchy it gets offset by 20 pixels (to keep it from hitting the status bar). However, this still occurs even when the view in question is nowhere near the top.
This is reproducible in Interface Builder, and an easy workaround for me has been to reorder my views so that a label or button is first under the view controller's view. If that's not possible in your case, adding an empty view (even off screen) above your scrollview also seems to solve the problem.
I added this to my UIViewControllers in viewDidLoad: which were affected and it fixed the issue for me:
NSComparisonResult order = [[UIDevice currentDevice].systemVersion compare: #"7.0" options: NSNumericSearch];
if (order == NSOrderedSame || order == NSOrderedDescending)
{
// OS version >= 7.0
self.edgesForExtendedLayout = UIRectEdgeNone;
}
Another, cleaner method:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
How are you laying out your views? With autolayout you can use the topLayoutGuide, which should accommodate for these offsets.
In the Ios 7 the view starts from the window from y= 0, move your view to 20 pixel dowm
self.view.frame = CGRectmake (0,20,320,hight);
this is due to transparent status bar in iOS 7.
pull down the view to show it properly.
Related
I have created my own implementation of a UITabBar (just a UIView instance).
This UIView contains 3 TabBarItem instances. A TabBarItem is a UIView subclass, and each contains the following UI controls:
UIImageView
UILabel
TabBarBadge (custom UIView subclass)
I am laying out the view hierarchy in a storyboard using auto layout.
The badge for a tab bar item should be positioned so that the y-center of the badge is aligned with the top edge of the image view, and it should be aligned to the right side of the image view, with a 4 point overlap (so, left edge of badge aligned with right edge of image view, with a constant of -4).
This works fine when the app loads, whether in portrait or landscape mode. In either case, though, rotating the device ends up with the frame of the badge in the wrong place after rotation finishes.
Here's a printout from the console of the NSLayoutConstraint in question:
<NSLayoutConstraint H:[UIImageView]-(-4)-[TabBarBadge] (active)>
That's exactly what I would expect it to be.
Here's a printout from the console of the TabBarBadge in question (portrait mode; correct presentation):
<TabBarBadge frame = (80.6667 0; 36 20); text = '67'; autoresize = RM+BM>
Here's a printout from the console of the TabBarBadge in question (landscape mode; incorrect presentation):
<TabBarBadge frame = (80.6667 0; 36 20); text = '67'; autoresize = RM+BM>
So, you can see that the frame isn't changing/updating when the rotation occurs.
Here are a couple of screen shots:
Portrait, Correct Display
Landscape, Incorrect Display
Constraints (Printout of constraints above is from this view)
So, what has me confused is that the rest of the TabBarItem is updating correctly. The UIImageView and UILabel are automatically updating correctly. Why is this one frame not updating correctly?
So, first I researched whether a custom drawRect: method might be the cause of my problem. That doesn't appear to be a factor.
Then, I started noticing some odd discrepancies between the view's frame at different times, and how only this particular one (there are actually 3 in the app) was having the problem. The other 2 currently have no values displayed.
Then, I remembered that I use a UIDynamicAnimator when the value is changed to "bounce" the view, in order to bring attention to the new value.
So, the problem is actually that I wasn't "releasing" (in the control sense, not the memory sense) the view from the UIDynamicAnimator when I was done with the animation. (I'm still not sure whether that's a bug or not. It seems to me that if the animation is paused and the constraints should update the view's frame, then perhaps that should occur.)
So, here's the actual code that was "buggy":
- (void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator {
// {Other code}
}
And here's the code that fixed my issue:
- (void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator {
// {Other code}
// Code that fixed the issue:
[self.animator removeAllBehaviors];
}
If I need to animate the view again, I just re-create the animator anyway, so this seems to be the best fix.
This appears to be in agreement with Matt's answer here. (I didn't know this was an issue with UIDynamicAnimator when I asked the question.)
My app use uitabbar and uinavigationbar.but I encounter a problem in iOS7.1. if I switch page between one with navigationbar and one without navigationbar. the page have scrollview or uitableview,every time swith,self.view.frame or self.view.bounds is Correct,but scrollview or uitableview's frame is Correct but bounds.y every time swith will change 20px.one up,one down.
i try to change scrollview or uitableview's bounds.y in view will viewWillAppear.
CGRect bounds = contentScrollView.bounds;
bounds.origin = CGPointMake(0, 0);
contentScrollView.bounds = bounds;
but if i do it,ok,every time swith page is show right,but when i drag the scrollview or uitableview,the layout incorrect.
the demo has upload on github:https://github.com/KingCentLee/HSText
I hope someone can help me.the demo in iOS 7 later is normal. just iOS 7 swith page encounter the problem.and can tell the reason.Thank you.
I have seen your code. Try delete the code in viewWillAppear. I'am sorry, I don't have ios7 device. In my memory, it may cause by the system status bar which height is just 20px. This is only a suggestion. ps:I can't add a comment.
I've got the issue where my iOS6 app's UI overlaps with the status bar on iOS 7. I've read previous posting on here regarding how to fix this but I'm not getting results.
I have several views all contained within a view controller's main view:
Posted solutions to the status bar overlap issue suggest to add 20 to the Y origin and set a value of -20 to the delta Y to compensate.
The first issue is I can't set the origin in IB for my main high level view - its greyed out:
So instead in the VC's viewDidLoad a tried setting the origin manually:
- (void)viewDidLoad
{
CGRect frame = self.view.frame;
frame.origin.y = 20;
self.view.frame = frame;
However when I run the app there's no difference, I'm still getting the status bar overlapping.
I'm only making changes to the main view, as all the other views are children of the main view I was assuming if I adjust just that one everything else will shift relative to that.
How come I'm not seeing any difference after making a change to the origin?
try this combined with your proposed solution in viewDidLoad:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
Another thing you can try is setting the frame on viewdidappear if this does not work for you.
Good luck and upvote up if this works for you :)
I am newbie for iOS development. What I have done so far is as below.
Created New Project
Removed all controller and added View Controller.
Dragged ScrollView in ViewController
Dragged Tab Bar in ScrollView
Dragged 7 Tab Bar Item in Tab Bar.
Now when I execute this project, I have all 7 tabs on screen which is not looking good. So what I am planning is display only 4 tab at first and if user scroll it horizontally, user can scroll and see rest tabs.
So, what I want to achieve is programmatically set some parameter in ScrollView that it will display only first 4 options only.
Any idea/ suggestion on this to be done?
EDIT :
I think this one may be even more adapted to the situation. Contrary to KLHorizontalSelect, it's kind of old (no commit on the master branch for a year ?) and I have no experience with it, but it may solve your problem : InfiniTabBar.
The description is short :
A scrolling tab bar with space for infinite items
Maybe you can take a look at this control : KLHorizontalSelect.
Here's how it looks like :
I don't think it looks exactly as you want, but I think it works almost as what you're expecting. Maybe you can work on the design ?
You have no code used so far, but you'll absolutely have to do that to achieve this. I'll get you started:
Create a scrollview at the bottom of your viewcontroller. Create UIViews on it and make them have a width of 640 (iPhone Retina screen width). You can put a image and a title on the UIView and make them function as a button. Set the content size to 640/4 *7 and there you go. You can give the background of the scrollview the same image as the UITabBar, but you'll need this.
This snippet might help you:
for (int i = 0; i<7; i++){
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0 + 50*i,0, 50,50);
[scrollView addSubview:view];
}
You'll have to multiply the x origin with the width of the UIViews (plus some margin) to make sure they aren't all on the same spot.
I have a UIScrollView with a View inside of it. Inside of that view is a bunch of buttons, labels, etc that fit in the View when in Portrait mode...When the iPad is rotated, I want the scrollView to kick in so the user can scroll to the bottom of the view. The app runs, but when I rotate it, the scroller never works...I believe I've wired everything up correctly and I have this code in the viewDidLoad event:
[scrollview addSubview: masterView];
scrollView.contentSize = [masterView sizeThatFits:CGSizeZero];
Is there something else I am missing? Do I need to modify the size when the iPad rotates?
thanks
There may be a problem with the content size of the UIScrollView. Without the contentSize being set larger than the actual scrollView size, scroll bars won't be shown.
You can code this in with something like this:
[scrollView setContentSize:CGSizeMake(2000,2000)];
And then changing the content size to the actual content size of what you are putting in the UIScrollView (scrollView).
If you look at the results of [masterView sizeThatFits:CGSizeZero] (e.g. NSLog or set a breakpoint in your debugger, I think you will find that it's not what you expected it to be. You might find that masterView has autoResize parameters set (which is common for a view that covers the entire screen), which means that it might, itself, be getting resized too short to fit all of its controls and scrollView is simply grabbing this shortened value itself. Take a look at that CGSize and the problem will be obvious.
I faced similar situation but my case was iPhone.
Remember that content should be larger than scroll for scrollView to kick in.
"Why would you want to go down if everything is visible in front of you ?"
use the following code:
[scrollView setContentSize:CGSizeMake(intValue, intValue)];
intValue: Integer values setting width and height of scroll.
Even if it doesn't works, don't worry there are loads of other options to figure out the solution:
1. NSLog
2. Breakpoints
3. Put up errors you are getting from console on stackoverflow