iPhone top of gadgets cut off first time it is drawn - ios

I'm trying to put a ad on top of my iPad app. I have the y corder net as zero. It seems like the first time the add is drawn it is drawn with the y cordernt starting at the very top. So the bar with the battery power and internet strength gets drawn onto. If you clcim on the add, and then return to the app the add is dawn right under the battery stregth bar with the y cordet still zero.
If i set the y to 60, it will look good at first, but then when you click on the add bar and then return to the add, the add is drawn 60 pixels below the battery bar instead of right under neath it.
It seems like sometimes the y starts at the very top of the screen, then it starts right below the battery stretch bar.
There must be a way to fix this,......
code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
// AddCode
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
adView.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifierPortrait];
adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
[self.view addSubview:adView];
adView.delegate=self;
bannerIsVisible=NO;
}
// i removes all the code to make sure nothing was messing it up
#end

I suspect, if you play with it some you will find the issue is with the app launching in orientations other than portrait (either landscape or upside down).
I had a very similar problem and was able to get it working by fiddling with the wantsFullScreenLayout property on my UIViewController subclasses. The documentation of this property seems to imply that the correct value is NO, but try setting it to YES on your main view controller.

Related

UITableView as ScrollView Between Navigation and Tab Bars

I have a table view laid out between a navigation bar and a tab bar and want to achieve scrolling only for the table view section (so in other words, in my iOS Simulator, I would want the two bars to always be seen, and I should be able to scroll my table view between them).
Having tried out various suggestions from SO posts, afraid am still getting something wrong. Can you advise please how do I fix this issue - I've been struggling with it for the last 1 day!
In the table view controller's viewDidLoad, I use the following code. Earlier, I also tried initializing a scroll view separately but understand that table view is a sub-class of scroll view, so ditched that path...
- (void)viewDidLoad
{
[super viewDidLoad];
// To remove extra separators from the table view to prevent blank rows from showing.
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
// ***** Scroll view implementation *****
[[self tableView] setFrame:CGRectMake(0, self.navigationController.navigationBar.frame.size.height, self.view.frame.size.width, self.view.frame.size.height - self.navigationController.navigationBar.frame.size.height - self.tabBarController.tabBar.frame.size.height)];
[[self tableView] setContentSize:CGSizeMake(self.view.frame.size.width, 2000)];
[self setEdgesForExtendedLayout:UIRectEdgeNone];
self.automaticallyAdjustsScrollViewInsets = YES;
}
In fact, to test this further, I have created a scroll view in a separate tab (in this tabbarcontroller app) where I only have a navigation bar and a tab bar so far (no table view). Its viewDidLoad looks like this - somehow, no luck there as well... the scroll bar starts from the top of the screen (rather than from the bottom of the navigation bar) and goes till the bottom of the screen (rather than till the top of the tab bar). So clearly I'm doing something conceptually wrong here... appreciate if you can help out please!!! The numbers put in here are experimental to test this out but I've ensured that the content size is larger than the scroll view frame...
- (void)viewDidLoad
{
[super viewDidLoad];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 300)];
[scrollView setContentSize:CGSizeMake(self.view.frame.size.width, 1500)];
[self.view addSubview:scrollView];
[self setEdgesForExtendedLayout:UIRectEdgeNone];
self.automaticallyAdjustsScrollViewInsets = NO;
[scrollView setScrollEnabled:YES];
}
Finally, when I debug my app in the simulator, what is odd is that for the table view tab, the scroll bar does appear momentarily to start from below the navigation bar. But as soon as I touch the track pad to scroll, it disappears and a more prominent scroll bar appears and starts from the top of screen to the bottom of the screen as I mention initially above!
I think I found the underlying error in my ways. More than an implementation bug, it was me missing out on a very basic issue...
In summary, the iOS Simulator would typically always have higher resolution / number of pixels than the computer screen, and no matter what, the simulator would always outsize the computer screen unless manually resized. So the scroll bar would usually be always present. This SO post helped me understand it.
On the other hand, the UIScrollView was automatically already implemented in my table view, given that UITableView is a subclass of UIScrollView - I didnt have to do anything. I was scrolling the simulator with a 'light' double-touch, which was taking me to the scroll bar due to the issue mentioned above. If I 'hard-clicked' and then scrolled, then voila! The required UIScrollView did work properly as expected! This is probably what misled me to mention these statements in the question...!
Finally, when I debug my app in the simulator, what is odd is that for the table view tab, the scroll bar does appear momentarily to start from below the navigation bar. But as soon as I touch the track pad to scroll, it disappears and a more prominent scroll bar appears and starts from the top of screen to the bottom of the screen as I mention initially above!

Bounds automatically changes on UIScrollView with content insets

I'm using a UIScrollView as my paging scroll view, pagesScrollView. Inside that, I put individual UIScrollViews which are used exclusively for zooming. Inside each of those, I have one view which is the page item which should be zoomable. All of that is inside a UINavigationController with a translucent navbar.
My pagesScrollView has contentInset.top = 64 and bounds.origin.y = -64 (that seems weird to me, but that's what the system is setting automatically for me), and this works just fine. My screen looks great!
However, after I scroll the pagesScrollView even a tiny bit, as soon as scrollViewWillEndDragging is called, the pagesScrollView begins an animated change from bounds.origin.y = -64 to bounds.origin.y = 0 which causes my page items to be obscured by the navbar.
On the left is what it looks like when it loads, on the right is what it looks like after I drag just a few pixels and then let go, it slides up under the navbar (because the bounds.origin.y goes to 0).
The problem is that I don't have any code that is altering the bounds and I don't have any code in the various scroll delegate methods that do anything. I've added a bunch of scroll delegate methods and just added NSLog()s so I can figure out when/where the change is happening, but it's not happening anywhere in my code.
So, I don't know what code I can show you to help you help me.
EDIT: I built a new project from scratch to remove all other variables.. I put a bare UIViewController into a UINavigationController. I put a UIScrollView into my View the entire size of the view. The following code is the entire project.
It turns out the issue (described below) only appears once PAGING IS ENABLED on the UIScrollView! Wtf? :)
Here is a link to download a basic project with only a few lines of code which demonstrates the problem. Just click in the scrollview and you'll see it shift up as the bounds change. http://inadaydevelopment.com/stackoverflow/WeirdScrollViews.zip
How can I have paging enabled on my scrollview without the bounds freaking out during scrolling and shifting everything under the nav bar?
It's possible to set the navbar to opaque and the problem is avoided, but the ideal is to have standard iOS7 behavior so that after the content view is zoomed, THEN the content is allowed to be under the navbar and should show through the translucency normally.
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSArray *colors = #[
[UIColor blueColor],
[UIColor orangeColor],
[UIColor magentaColor],
];
NSArray *zoomerColors = #[
[UIColor greenColor],
[UIColor yellowColor],
[UIColor purpleColor],
];
self.scroller.pagingEnabled = YES;
[self.scroller setContentSize:CGSizeMake(self.scroller.frame.size.width*colors.count, self.scroller.frame.size.height)];
CGRect subviewFrame = CGRectMake(0, 0, 160, 240);
for (int index=0; index < colors.count; index++) {
UIColor *color = [colors objectAtIndex:index];
UIColor *zoomerColor = [zoomerColors objectAtIndex:index];
UIView *subview = [[UIView alloc] initWithFrame:subviewFrame];
subview.backgroundColor = color;
CGRect zoomerFrame = CGRectMake(index*self.scroller.frame.size.width, 0, self.scroller.frame.size.width, self.scroller.frame.size.height);
UIScrollView *zoomer = [[UIScrollView alloc] initWithFrame:zoomerFrame];
[zoomer addSubview:subview];
zoomer.backgroundColor = zoomerColor;
[self.scroller addSubview:zoomer];
}
}
Just switch off Adjust Scroll View Insets
It's an iOS bug. I created the following subclass of UIScrollView to get a log of what happens to y over time and who was pushing it:
#implementation CSScrollView
- (void)setContentOffset:(CGPoint)contentOffset
{
NSLog(#"%0.0f %#", contentOffset.y, [NSThread callStackSymbols]);
NSLog(#"[%#]", self.layer.animationKeys);
[super setContentOffset:contentOffset];
}
#end
(and changed the view class in the storyboard)
When you release your finger, a method called UIScrollView _smoothScrollDisplayLink: starts animating the scroll view to its final position. As per the second log, there's no CAAnimation involved, the scroll view uses its own display link to do its own transition. That custom code appears to make the mistake of animating from y = whatever to y = 0, failing to take the content offset into account.
As a proof-of-concept hack I changed the code to:
#implementation CSScrollView
- (void)setContentOffset:(CGPoint)contentOffset
{
contentOffset.y = -64.0f;
[super setContentOffset:contentOffset];
}
#end
And, unsurprisingly, the problem went away.
You probably don't want to hard code the -64.0f but I'd conclude:
it's an iOS bug;
work around it by rejecting nonsensical values via a subclass of UIScrollView with a suitable custom implementation of - setContentOffset:.
A sensible generic means might be to check the state of self.panGestureRecognizer — that'll allow you to differentiate between scrolls the user is responsible for and other scrolls without relying on any undocumented API or complicated capturing of delegate events. Then if necessary crib the correct contentOffset.y from the current value rather than hardcoding it.
My pagesScrollView has contentInset.top = 64 and bounds.origin.y = -64 (that seems weird to me, but that's what the system is setting automatically for me), and this works just fine. My screen looks great!
It because of iOS 7 sets contentInset.top to 64 on all scrollviews.
Just add this line of code into your view controller and all will work as expected:
-(UIRectEdge)edgesForExtendedLayout {
return UIRectEdgeNone;
}
I checked on your example project.
I have checked you example use below code in viewController.m file
-(void)viewDidLoad
{
if ([[UIDevice currentDevice] systemVersion].floatValue>=7.0) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
}
It's working fine...
It turns out the issue (described below) only appears once PAGING IS ENABLED on the UIScrollView! Wtf? :)
As you said that, If you enable the scroll paging, the UIScrollView will stop at a paging edge after a dragging or any movement, which is promised by the framework. Bounds.origin.y set by zero means that the first page edge matched the scroll view frame edge, cuz you have 64 contentInsets there. So that's not bug, that is what it is. And since your bar is translucent, remember where is your scroll view's frame edge, it's under the bar. In a word, this is not a bug, I think, but a effect of scroll paging.

Finding The Center of a View

I have an iphone app with 2 ViewControllers . Both screens(viewcontrollers) show a loading screen. I create the loading screen programmatically:
UIView *loadingScreen = [[UIView alloc] initWithFrame:CGRectMake(100,200,144,144)];
loadingScreen.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
//{.. Other customizations to loading screen
// ..}
[self.view addSubview:loadingScreen];
For some reason, the second viewcontroller's loadingScreen is significantly lower and it isn't centered on the screen. The first viewcontroller works perfectly and is dead center like I want.
The second viewcontroller is a UITableView and it shows the uinavigationbar, whereas the first viewcontroller doesn't show the uinavigationbar. Also, I use storyboard for my app.
I've outputted to the NSLog self.view.frame.size.height and loadingScreen.center in both instances and THEY HAVE THE SAME COORDINATES! So, not sure why it is showing up lower. Any ideas why the second loadingScreen is lower and how to fix? Thanks!
You mention that one screen displays a UINavigationBar while the other does not. When you display a navigation bar, it offsets the rest of your view - in this case by shifting it down.
There are two quick fixes. You can either adjust your center point up by the size of the UINavigationBar (65 pts - unless it's a custom UINavigationBar and you've changed its size) or you can set the "Adjust Scroll View Insets" value to false in the attributes inspector.
The latter is probably the easiest and comes most recommended. Note though, that the top of your UITableView will now be underneath the UINavigationBar.
My final note would be that if you wanted to do it programmatically than in your UITableView's delegate you can call
- (BOOL)automaticallyAdjustsScrollViewInsets
{
return NO;
}

Funny UIScrollView when using presentViewController

Summary:
I have a UIScrollView with zoomable content. If the content is NOT zoomed and I presentViewController, everything is fine when I dismiss that ViewController. But, if I have zoomed the content and then presentViewController, the content and the UIScrollView are all wacky when I dismiss the ViewController. Any help is welcome, this is an awful bug... Thank you!
Test Project:
A simple test can be found here...
http://twostatesaway.com/ModalWithScrollViewTEST.zip
or here
https://drive.google.com/file/d/0B0pG5vRVzBTzdkVzdEtkdmVjdDA/edit?usp=sharing
Screen Shots:
Screen 1: Everything fine. I can show the modal a million times and the content will work as expected after dismissing the modal
Screen 2: Zoom in on content.
Screen 3: When I click the button to presentViewController, the content shifts to the right as the ViewController (in black) is coming up.
Screen 4: Modal is on screen.
Screen 5: When I dismiss the ViewConroller, the content is funny, the bright green view seems to go back to normal, but the button stays in its zoom position, still shifted to the right.
Screen 6: Another funny things is that now I can zoom out more than before. The min zoom is set at 1.0, but now it seems like that is not working.
Try this way...
1) Remove the code from - (IBAction)openModal:(id)sender & make it blank.
2) In story board make the secondViewController class as ModalViewController as below.
3) Drag the line from button to second view & use segue as modal as shown below.
Updated answer
1) clear the viewDidLoad method.
2) Write following code in ViewWillAppear method.
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.scrollView.delegate = self;
self.scrollView.minimumZoomScale = 1.0;
self.scrollView.maximumZoomScale = 5.0;
//self.scrollView.contentSize=CGSizeMake(320, 200);
[self.scrollView setZoomScale:self.scrollView.minimumZoomScale];
}
The accepted work around here is to capture the zoom and contentOffset when the modal is coming up, and then set the properties when view is appearing again...
//// Capture values
-(void)viewWillDisappear:(BOOL)animated
{
zoomedScale = self.scrollView.zoomScale;
contentOffsetTemp = self.scrollView.contentOffset;
}
//// This prevents the content from getting messed up (thanks user1673099)
-(void)viewDidDisappear:(BOOL)animated
{
[self.scrollView setZoomScale:self.scrollView.minimumZoomScale];
}
//// Then reassign them values
-(void)viewWillAppear:(BOOL)animated
{
self.scrollView.zoomScale = zoomedScale;
self.scrollView.contentOffset = contentOffsetTemp;
}

Storyboard white space at top in all model controllers

Am getting a white space at top in all containers. if I do a model transition that white space is clearly visible on top of all navigation controllers.
that space is around 20px.
How to remove this white space..??
Any suggestion ???
You didn't really give us enough details in your question, but the most likely cause for your problem is that you are instantiating the subviews programmatically for your viewcontrollers using the viewcontroller's view frame rather than the bounds.
If in your viewDidLoad method you do something like:
- (void)viewDidLoad
{
[super viewDidLoad];
MyView* myView = [[MyView alloc] initWithFrame:self.view.frame];
[self.view addSubview:myView];
}
then your view will be initialized with an offset of 20px, because your self.view.frame's origin is (0, 20), in order to not overlap with the navigation bar. If you then set your subview's frame with that same origin, it means that the view's origin will be 20 px further translated down (it's not really pixels but points, as the value stays the same whether it's a retina display or not, but whatever).
So, if you want to add a subview that is the size of the view controller's view that is presenting it, then you should always initialize it with:
MyView* myView = [[MyView alloc] initWithFrame:self.view.bounds];
I hope this helps, you didn't give us much to work with in your question, in the future try to give us (many many) more details about what it is that you do, both in the code and in the storyboard.

Resources