iPhone : Hiding / showing Toolbar - iphone

I have a toolbar on top of my view with a back button. I would like when the view loads to appear with the toolbar hidden and then, with a touch of the button to appear animated.
--Edit--
I am not using a Navigation Controller.

Before the view is shown:
[self.navigationController setToolbarHidden:YES];
When you press the button:
[self.navigationController setToolbarHidden:NO];

Given new information - that there's no UINavigationController - things are different. Here are the relevant bits from my code...
Create the nav bar and add it to your view:
// Create the navigation bar
self.navBar = [[UINavigationBar alloc] init];
[self.view addSubview:self.navBar];
Lay it out..
- (CGRect)frameForOrientation:(UIInterfaceOrientation)theOrientation
{
UIScreen *screen = [UIScreen mainScreen];
CGRect fullScreenRect = screen.bounds; // always implicitly in Portrait orientation.
CGRect appFrame = screen.applicationFrame;
// Find status bar height by checking which dimension of the applicationFrame is narrower than screen bounds.
// Little bit ugly looking, but it'll still work even if they change the status bar height in future.
float statusBarHeight = MAX((fullScreenRect.size.width - appFrame.size.width), (fullScreenRect.size.height - appFrame.size.height));
// Initially assume portrait orientation.
float width = fullScreenRect.size.width;
float height = fullScreenRect.size.height;
// Correct for orientation.
if (UIInterfaceOrientationIsLandscape(theOrientation)) {
width = fullScreenRect.size.height;
height = fullScreenRect.size.width;
}
// Account for status bar, which always subtracts from the height (since it's always at the top of the screen).
height -= statusBarHeight;
return CGRectMake(0, statusBarHeight, width, height);
}
- (CGSize)viewSizeForOrientation:(UIInterfaceOrientation)theOrientation
{
CGRect frame = [self frameForOrientation:theOrientation];
return CGSizeMake(frame.size.width, frame.size.height);
}
- (void)layoutSubviewsForInterfaceOrientation:(UIInterfaceOrientation)theOrientation withAnimation:(BOOL)animate
{
CGSize fullSize = [self viewSizeForOrientation:theOrientation];
float width = fullSize.width;
float height = fullSize.height;
CGRect newFrame = CGRectMake(0, 0, width, height);
SubViewController *controller;
UIView *theView;
// Place the navigation bar
CGRect navBarFrame = newFrame;
navBarFrame.size.height = NAVBARHEIGHT;
self.navBar.frame = navBarFrame;
}
Create a function to who it/hide it:
- (void)showNavigationBar:(BOOL)show
{
if (show == YES && self.navBar.hidden == YES) {
// Move the frame out of sight
CGRect frame = self.navBar.frame;
frame.origin.y = -frame.size.height;
self.navBar.frame = frame;
// Display it nicely
self.navBar.hidden = NO;
frame.origin.y = 0.0;
[self.view bringSubviewToFront:self.navBar];
[UIView animateWithDuration:0.3
animations:^(void) {
self.navBar.frame = frame;
}
];
}
else if (show == NO && self.navBar.hidden == NO) {
CGRect frame = self.navBar.frame;
// Display it nicely
frame.origin.y = -frame.size.height;
[self.view bringSubviewToFront:self.navBar];
[UIView animateWithDuration:0.3
animations:^(void) {
self.navBar.frame = frame;
}
completion:^(BOOL finished) {
self.navBar.hidden = YES;
}
];
}
}
where
#define NAVBARHEIGHT 44

Here's some of tarmes's code ported to MonoTouch/c#.
public static RectangleF FrameForOrientation(UIInterfaceOrientation orientation) {
var screen = UIScreen.MainScreen;
var fullScreenRect = screen.Bounds; // always implicitly in Portrait orientation.
var appFrame = screen.ApplicationFrame;
// Find status bar height by checking which dimension of the applicationFrame is narrower than screen bounds.
// Little bit ugly looking, but it'll still work even if they change the status bar height in future.
var statusBarHeight = Math.Max((fullScreenRect.Width - appFrame.Width), (fullScreenRect.Height- appFrame.Height));
// Initially assume portrait orientation.
var width = fullScreenRect.Width;
var height = fullScreenRect.Height;
// Correct for orientation.
if (IsLandscapeOrientation(orientation)) {
width = fullScreenRect.Height;
height = fullScreenRect.Width;
}
// Account for status bar, which always subtracts from the height (since it's always at the top of the screen).
height -= statusBarHeight;
return new RectangleF(0, statusBarHeight, width, height);
}
public static SizeF SizeForOrientation(UIInterfaceOrientation orientation) {
var frame = FrameForOrientation(orientation);
return new SizeF(frame.Width, frame.Height);
}
public static bool IsLandscapeOrientation(UIInterfaceOrientation orientation) {
return
orientation == UIInterfaceOrientation.LandscapeLeft ||
orientation == UIInterfaceOrientation.LandscapeRight;
}

Related

ScrollView Swipe Right not working XCode

I've a scrollView in which subviews are added and these subviews can be swiped top, right and left. But for some reason the swipe right does not seem to be working at all. I'm completely new to Objective-C, due to which i've been struggling real hard to make it work. I've a main view controller implementation with following code:
my MainViewController.m is
- (void)viewDidLoad {
[super viewDidLoad];
_headerViewController = [self.storyboard instantiateViewControllerWithIdentifier:kHeaderId];
_headerViewController.delegate = self;
[scrollView addSubview:_headerViewController.view];
_actionsListViewController = [self.storyboard instantiateViewControllerWithIdentifier:kActionsListId];
_actionsListViewController.delegate = self;
[scrollView insertSubview:_actionsListViewController.view
belowSubview:_headerViewController.view];
_agendasListViewController = [self.storyboard instantiateViewControllerWithIdentifier:KAgendasListId];
_agendasListViewController.delegate = self;
[scrollView insertSubview:_agendasListViewController.view
belowSubview:_headerViewController.view];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self positionSearchField:YES];
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * 2,
scrollView.frame.size.height * 2);
_headerViewController.view.frame = CGRectMake(0, 0,
scrollView.frame.size.width,
scrollView.frame.size.height);
//action view will be displayed when swiped left
_actionsListViewController.view.frame = CGRectMake(scrollView.frame.size.width, 0,
scrollView.frame.size.width,
scrollView.frame.size.height);
//agenda view should have been displayed when swiped right
_agendasListViewController.view.frame = CGRectMake(-scrollView.frame.size.width, 0,
scrollView.frame.size.width,
scrollView.frame.size.height);
_scrollViewBounds = scrollView.bounds;
}
and the viewShouldScroll function
- (void)viewShouldScroll:(UISwipeGestureRecognizerDirection)direction {
CGRect frame = CGRectMake(scrollView.contentOffset.x,
scrollView.contentOffset.y,
scrollView.frame.size.width,
scrollView.frame.size.height);
UIViewController *currentController = [self visibleViewController];
switch (direction) {
case UISwipeGestureRecognizerDirectionUp:
frame.origin.y += scrollView.frame.size.height;
break;
case UISwipeGestureRecognizerDirectionLeft:
//works fine and displays action view
frame.origin.x += scrollView.frame.size.width;
break;
case UISwipeGestureRecognizerDirectionDown:
frame.origin.y -= scrollView.frame.size.height;
break;
case UISwipeGestureRecognizerDirectionRight:
if( currentController == _headerViewController ) {
//does not work for agenda when swiped right
NSLog(#"x position is %f#", frame.origin.x);
frame.origin.x = -320; //hardcoded to check if this works, but doesnot
NSLog(#"width is %f#", scrollView.frame.size.width); //gives -320
}
else {
//works fine when swiped from left to right to show main view
frame.origin.x -= scrollView.frame.size.width; //0
}
break;
default:
break;
}
[scrollView scrollRectToVisible:frame animated:YES];
}
Gesture recognizers have been added from storyboard for LEFT, RIGHT and TOP. As per the code, i've added agenda view with position of x as -320 in CGRectMake and on swipe right, i'm trying to make it visible by changing the x point of frame.origin but it does not seem to work. Any help would be appreciated.
I managed to do it this way::
...
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * 3,
scrollView.frame.size.height * 2);
...
I was using the width of scrollView as scrollView.frame.size.width * 2, which made the total width of scroll view double of scrollView.frame.size.width, but since i had 3 subviews in the main scrollView, i needed to do create scrollView with width 3 times the width of scrollView frame as scrollView.frame.size.width * 3

jump to pages in a scrollview that is using UIPagecontrol

I have UIScrollview that contains different UITableviews. You can scroll through these UITableviews using a UIPagecontrol.
This is how I add my UITableview to the UIScrollview
- (void)loadPage:(NSInteger)page {
if (page < 0 || page >= self.pageStages.count) {
// If it's outside the range of what we have to display, then do nothing
return;
}
// Load an individual page, first seeing if we've already loaded it
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null]) {
CGRect frame = self.scrollView.bounds;
//frame.size.width = 280.0f;
frame.size.height = self.scrollView.bounds.size.height;
float offset=20;
frame.size.width = frame.size.width-(2*offset);
frame.origin.x = (326 * page)+offset;
frame.origin.y = 0;
UITableView *tableStage = [[UITableView alloc]initWithFrame:frame];
tableStage.backgroundColor = [UIColor colorWithRed:(250/255.0) green:(248/255.0) blue:(247/255.0) alpha:100];
tableStage.contentMode = UIViewContentModeScaleAspectFit;
tableStage.delegate = self;
tableStage.dataSource = self;
tableStage.tag = page;
tableStage.contentMode = UIViewContentModeScaleAspectFit;
[self.scrollView addSubview:tableStage];
[self.pageViews replaceObjectAtIndex:page withObject:tableStage];
}
}
Now I want that user can jump to a certain UITableview from another UIViewController. Therefore I have a variable pageNumber. When I set the pageNumber I call a method jumpToPage3 and I give the pageNumber with it. This is how the function looks like.
-(void)jumpToPage3:(NSNumber *)page{
NSLog(#"jump to page 3");
float offset=30;
float height = self.scrollView.bounds.size.height;
float width = 320 - (2*offset);
int pagee = [page intValue] - 1;
float x = (320 * pagee) + offset;
[self.scrollView scrollRectToVisible:CGRectMake(x, 0, width , height) animated:NO];
}
The problem is that it is not jumping to the correct page. It stays on the first page.
Can someone help me with this?
When you add content to the scroll view you also have to tell increase the contentSize

Gap between subviews of UIScrollView

I have two subviews of UIScrollView. One is textView and other is tableView. I made textview's height flexible based on its content, but I have one problem. If the text in the textview (which is parsed data) is small, there is a big gap between textview and tableview. Or if the text is too large then it covers the tableview. How can I keep the same gap between textview and tableview irrespective of the amount of content of text view? This is all done in IB.
Thanks.
you must handle both textview and tableview position dynamically like ur text view height and y-axis is
y-axis 10; height 40;
now in tableview setframe:cgrectmake(your X coordinate, textview.frame.size.height+20)
so its always show same difference between textview and tableview if your textview height is 60 than tableview y point is 60+20
- (void)loadView
{
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.showsVerticalScrollIndicator = NO;
pagingScrollView.showsHorizontalScrollIndicator = NO;
pagingScrollView.contentSize = CGSizeMake(pagingScrollViewFrame.size.width * [self imageCount],
pagingScrollViewFrame.size.height);
pagingScrollView.delegate = self;
self.view = pagingScrollView;
}
- (CGRect)frameForPagingScrollView {
CGRect frame = [[UIScreen mainScreen] bounds];
frame.origin.x -= PADDING;
frame.size.width += (2 * PADDING);
return frame;
}
- (CGRect)frameForPageAtIndex:(NSUInteger)index {
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
CGRect pageFrame = pagingScrollViewFrame;
pageFrame.size.width -= (2 * PADDING);
pageFrame.origin.x = (pagingScrollViewFrame.size.width * index) + PADDING;
return pageFrame;
}

How to set a minimum UIPopoverController size in iOS 5?

I am using a UIPopoverController to display properties of my ContentItems. All worked fine in iOS 4.3 using presentPopoverFromRect. Some of the ContentItem rect's are fairly large, and in iOS 5, the popover re-sizes itself to fit in the margin between the rect's edges and the screen borders. In the worst cases the popover is less than 50 pixels tall and overlays the NavigationBar. Obviously not user friendly.
I've re-written the code (latest attempt below) to detect the problem cases and give the popover a 1 pixel rect at the center point of the ContentItem. This works most of the time although I'm still reverse-engineering the behavior for some boundary cases.
However I feel I must be missing something. During the iOS 5 Beta there was some discussion of the need to specify resizing masks of the Views the popover managed - but I just find it hard to believe the behavior I'm seeing is Apple fault and not mine. Advice is appreciated.
- (IBAction)handleDoubleTap:(UIGestureRecognizer *)sender
{
int subViewTag = sender.view.tag;
DLog(#":tag = %d", subViewTag);
NSString* key = [NSString stringWithFormat:#"%d", subViewTag];
ContentItemView* contentItemView = [self.contentItemViewDict objectForKey:key];
ContentItem* theContentItem = [contentItemView contentItem];
ContentItemPropertiesViewController* contentPopover = [[[ContentItemPropertiesViewController alloc] initWithNibName:#"ContentItemPropertiesViewController"
bundle:[NSBundle mainBundle]] autorelease];
contentPopover.delegate = self;
contentPopover.theItem = theContentItem;
contentPopover.theView = sender.view;
[contentPopover setContentSizeForViewInPopover:/*k_contentItemPopoverSize*/ CGSizeMake(320, 344.0f)];
UIPopoverController* popover = [[UIPopoverController alloc] initWithContentViewController:contentPopover];
popover.delegate = self;
self.contentPopoverViewController = popover;
[popover setPopoverContentSize:CGSizeMake(320, 344.0f)];
[popover release];
// Check to see if there's room for the popover around the edges of the object
CGRect popoverRect = [self rectForPopover:sender.view.frame];
if (popoverRect.origin.x == 0 && popoverRect.origin.y == 0 &&
popoverRect.size.width == 0 && popoverRect.size.height == 0) {
popoverRect = sender.view.bounds;
}
CGRect theRect = [sender.view convertRect:popoverRect
toView:self.view];
DLog(#"popoverRect %f, %f, %f, %f", theRect.origin.x, theRect.origin.y, theRect.size.width, theRect.size.height);
[self.contentPopoverViewController presentPopoverFromRect:theRect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
- (CGRect)rectForPopover:(CGRect)viewRect
{
#define k_popoverPad 30.0f // a little extra room for the popover borders and arrow
DLog();
// Get the width and height the popover controller needs to fully display itself
CGSize popoverSize = k_contentItemPopoverSize;
CGFloat popoverWidth = popoverSize.width;
CGFloat popoverHeight = popoverSize.height;
// Get the edges of the object's rect translated to sceneView's coordinates
CGFloat leftEdge = self.sceneView.frame.origin.x + viewRect.origin.x - k_popoverPad;
CGFloat rightEdge = leftEdge + viewRect.size.width + k_popoverPad;
CGFloat topEdge = self.sceneView.frame.origin.y + viewRect.origin.y - k_popoverPad;
CGFloat bottomEdge = topEdge + viewRect.size.height + k_popoverPad;
// Get the bounds of the view
CGFloat viewRightBound = self.view.bounds.origin.x + self.view.bounds.size.width;
CGFloat viewBottomBound = self.view.bounds.origin.y + self.view.bounds.size.height;
// Compare the "margin" between the screen bounds and object's edges
// to see if the popover will fit somewhere
if (leftEdge > popoverWidth || // room on the left
topEdge > popoverHeight || // room at the top
viewRightBound - rightEdge > popoverWidth || // room to the right
viewBottomBound - bottomEdge > popoverHeight) { // room at the bottom
return CGRectZero;
} else {
// return a rect that is (essentially) the centerpoint of the object
CGRect newRect = CGRectMake((rightEdge - leftEdge) / 2.0f, (bottomEdge - topEdge) / 2.0f, 1.0f, 1.0f);
return newRect;
}
}

UIScrollView Rotation Issues

I have a scrollview that automatically generates a series of subviews containing imageviews. The concept is that it's pretty much a custom PDF style reader, where each page is loaded in to an imageview as an image. There are three "layers" - the outer UIScrollView, the automatically generated subViews and the imageview inside the subview.
I've been having some trouble with this, I've asked the question previously, but unfortunately, the core of my question was in the wrong place. Here is my second attempt:
On rotate, everything is rotated as needed. Unfortunately, this is what I'm getting:
Obviously, I would like Image 1 to be centred and for there to be no hint of image 2 until you flick the view across.
Here is my code for setting up the view:
- (void)loadView {
[self setUpView];
}
- (void)setUpView {
//INITIALISE PAGING SCROLL VIEW
CGRect pagingScrollViewFrame = [[UIScreen mainScreen] bounds];
pagingScrollViewFrame.origin.x -= 10;
pagingScrollViewFrame.size.width += 20;
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.contentMode = UIViewContentModeScaleAspectFit;
//CONFIGURE PAGING SCROLL VIEW
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.contentSize = CGSizeMake(pagingScrollViewFrame.size.width*7, pagingScrollViewFrame.size.height);
//ACTIVATE PAGING SCROLL VIEW
self.view = pagingScrollView;
//ADD PAGES TO SCROLL VIEW
for (int i = 0; i < 7; i++){
ImageScrollView *page = [[[ImageScrollView alloc] init] autorelease];
[self configurePage:page forIndex:i];
[pagingScrollView addSubview:page];
}
}
How do I re-define the size of the frame? What function should I call etc. How do I centre the image?
I'm new to this so I apologise for the ambiguity of my question.
Cheers
I've figured it out. It was the Frame of the individual pages that I needed to change, so (with the help gained from another question) I wrote a re-orient method.
The first step to this came because I figured out that I needed to iterate through and re-size each frame for each of my pages and then re-apply the frames to the view. For this to happen I needed to create an array which I would fill in the For Loop above. I have 7 total pages.
Then I could (on rotate) call the below re-orient method to re-size each view:
- (void) reOrient{
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
CGRect f;
int i = 0;
for (ImageScrollView *page in pageArray) {
f = page.frame;
f.size.width = 320;
f.origin.x = (f.size.width * i);
page.frame = f;
pagingScrollView.contentSize = CGSizeMake(f.size.width * 7, 480);
i++;
}
}else{
CGRect f;
int i = 0;
for (ImageScrollView *page in pageArray) {
f = page.frame;
f.size.width = 480;
f.origin.x = (f.size.width * i);
page.frame = f;
pagingScrollView.contentSize = CGSizeMake(f.size.width * 7, 480);
i++;
}
}
}
This worked for me:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
//get current page based on offset before rotation
NSInteger currentPage = self.scrollView.contentOffset.x / self.scrollView.bounds.size.width;
//set anticipated scrollview content size by switching width and height (they will be switched after rotation)
[self.scrollView setContentSize:CGSizeMake(totalPages * self.view.bounds.size.height, self.view.bounds.size.width)];
//set the anticipated content offset based on height before rotation
[self.scrollView setContentOffset:CGPointMake(currentPage * self.scrollView.bounds.size.height, 0.0f)];
}
Basically I am setting the content offset for the new scrollview content size before rotating (I'm switching height and width for the anticipated height and width).
This worked for me when rotating a full-screen paged UIScrollView.
All of the paged subviews have the following autoresizing mask so that they neatly fall into place after rotation:
UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin