Scroll View with Navigation Bar within another Scroll View - ios

I have an app with three view controllers that the user can swipe between. The app loads up on the middle view controller. I am trying to create a sort of help screen, made up of a scroll view containing 3 images that the user can swipe between, as well as a navigation bar at the top to allow the user to exit the help screen. This help screen is to be displayed on top of the main scroll view, leaving 20px margin all the way around.
This is my code so far, creating the help scroll view:
if ([[ UIScreen mainScreen ] bounds ].size.height == 568 ) {
NSArray *images = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"Guide Page One.png"], nil];
self.helpScrollView.contentSize = CGSizeMake(280 * 3, 528);
self.helpScrollView.pagingEnabled = YES;
CGFloat xPos = 0.0;
for (UIImage *image in images) {
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(xPos, 0.0, 280, 528);
[self.scrollView addSubview:imageView];
xPos += 280;
// assuming ARC, otherwise release imageView
}
This was me trying to get it to work on the 4" screens. When I ran the simulator, the one image in the scroll view was shown on the far left of the main scroll view, and had no navigation bar.
This is how my xib is set out:
And here is the result:
The main scroll view still scrolls. I do not want this. Basically what I want is for this help scroll view to show up with my images, and allow the user to scroll through them before closing it, and continouing to the main app.
How can I do this?

Your ImageView is added on the top of layer stack when [self.scrollView addSubview:imageView] is executed, so it just hides the NavigationBar
Your helpScrollView seems to be wrong positioned. You may add constraints to properly position it.
If you want main ScrollView not to respond touches you should set mainScrollView.scrollEnabled=NO before displaying help ScrollView and when it hides set nack to YES;

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!

iOS View gets reset on addSubview

I have a storyboard with a square imageView in the middle at: 280,140 (vertical)
When the application starts i am able to move this imageView by pressing buttons. I move the imageView using:
_mainImage.frame = CGRectMake(_mainImage.frame.origin.x + 2, _mainImage.frame.origin.y, _mainImage.frame.size.width, _mainImage.frame.size.height);
while the application is running i keep adding new imageViews to the mainView:
UIImageView *imgView;
imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, yCoordinate, 50, 10)];
imgView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:imgView];
each time i call this code the square imageView i have placed in the middle and moved around, gets set back to its starting position. It seems like the mainView gets "reset" each time the addSubview gets called. Is there any way i can add a subview without having the mainView "reset"?
Most likely your view is set up using Autolayout (this is the default for storyboards or nibs) and when you add a new subview, a layout pass is performed which resets your views position back to that defined by its original constraints.
You should move your view by updating its constraints, or turn off Autolayout. There are lots of posts around explaining how to do either of these things.

Screen bounds extends visible area

I'm trying to make a square (50 x 50) UIView in the lower right hand of my main view, but I'm confused about why it's not entirely visible. In this instance, only the tip of it is visible from the bottom. Am I confusing some concept?
CGFloat width = CGRectGetWidth(self.view.bounds);
CGFloat height = CGRectGetHeight(self.view.bounds);
UIView *transparentFloater = [[UIView alloc] initWithFrame:CGRectMake(width - 50.f, height - 50.0f, 50.0f, 50.0f)];
[self.view addSubview:transparentFloater];
Try to add the autoresizing mask:
transparentFloater.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
If I am not wrong, You have created your ViewController with xib and in the attributes of view, you have forgot to mention that you are using a "navigation bar" as "top bar".
Reason
So in ViewDidLoad, view in .xib with a height X is returned. But as you might have loaded the viewController using UINavigationController, after loading the height of view is decreased by 44pixels.
Suggestions :
1) Whenever you know that you are going to have navigation bar on top please mention it in .xib file as well.
For doing so click on the view in xib and select the option called topbar in attributes Inspector of utilities area
2) Call the following api
NSLog(#"In ViewDidAppear %#",NSStringFromCGRect(self.view.bounds));
in
viewDidLoad
viewDidAppear
to track whats happening with the bounds of view
You does not need to do anything just put
transparentFloater.backgroundColor = [UIColor redColor];
because your view (custom) is invisible (because your main view color and custom view color are same (white) ) may be. I tried your code in my demo project. it worked perfectly for me.

How come a UIViewController's view coordinate system starts after the navbar, but its height includes the navbar?

I noticed that with a NavigationController on an iPhone, the height is 460. So it includes the whole screen except the status bar.
However, when I add something at coordinate 0, it shows up after the NavigationBar, although the size of the navigation bar is included in the height (meaning the entire frame of this view sticks off the screen).
Did I make a mistake? If not, why is it structured this way?
NSLog(#"Frame: %#", [NSValue valueWithCGRect: self.view.frame]); // prints {(0, 20), (320, 460)}
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame: CGRectMake(0, self.navigationController.navigationBar.frame.size.height, self.view.frame.width, 50)];
[self.view addSubview: scrollView]; // showing up 44px *after* the nav bar
I already answered your other similar question, but here is one for this.
In viewDidLoad you will see the views height as 460 because at that point it hasn't resized to account for the Nav Bar.
But If you printed the same frame out in say viewWillAppear you will see that now the frames height has adjusted for the Nav Bar.
So if you want to add something in viewDidLoad, you need to add it based on the views frame, add whichever resizing mask will do the job you want, and see it adjust correctly once the view appears.

adjusting view after hiding navigation bar

I have an app that has both navigationbar and toolbar on display with various buttons...
I have an imageview that will act as a help overlay (like you see in many apps these days) that is semi transparent with arrows pointing to the buttons on the bars plus actual view content.
First attempt displays the imageview in the view area but leaving the bars in place...not good!
So next attempt I have included the bars as part of the imageview and add this to take up the entire screen, so far so good. I then hide the bars but oh no.....the view moves up 44 pixels (as expected)
Problem is no matter what I do I cannot get the view to move down the 44 pixels?
So the imageview displays the bars giving the illusion the overlay (imageview) is on top, but the view in between is out of whack!
Does anyone know how to resolve this?
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(20, 0, 750, 1024)];
iv.userInteractionEnabled = YES;
iv.image = [UIImage imageNamed:#"myimage.png"];
UIWindow *window = self.view.window;
[window addSubview:iv];

Resources