I'm trying to make UIScrollView auto-resize and appear correctly in Landscape mode. Portrait mode works fine.
Here's my code:
- (void)viewDidLoad {
[super viewDidLoad];
//=== load all the custom view
NSMutableArray *controllers = [[NSMutableArray alloc] init];
int page = 0;
[controllers addObject:[self loadScrollView:[[Page1ViewController alloc] initWithNibName:#"Page1ViewController" bundle:nil] withPage:page++]];
[controllers addObject:[self loadScrollView:[[Page2ViewController alloc] initWithNibName:#"Page2ViewController" bundle:nil] withPage:page++]];
[controllers addObject:[self loadScrollView:[[Page3ViewController alloc] initWithNibName:#"Page3ViewController" bundle:nil] withPage:page++]];
self.viewControllers = controllers;
[controllers release];
//=== automaticaly define number of pages
_numberOfPages = [self.viewControllers count];
// a page is the width of the scroll view
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * _numberOfPages, scrollView.frame.size.height);
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.delegate = self;
// First, set the number of pages
pageControl.numberOfPages = _numberOfPages;
pageControl.currentPage = 0;
}
Then, I went into each view controller nib file and set the background to different color to test if it's working. Unfortunately, when in Landscape mode, the width and height remains the same as in Portrait Mode.
I'm not sure how to fix this problem. Hope anyone can help me.
Many thanks in advance.
I'm having the same problem, but only if I open the view in Landscape, when it was designed in the .xib in Portrait.
If I open in portrait, then rotate the device, it sizes correctly.
I've found that if I load my view controllers array in viewWillAppear, rather than in viewDidLoad, it sizes correctly all the time.
Related
I've successfully hooked up several popover views in interface builder. I've tried to make the background black by setting the view background color to black, but I am still getting a white arrow on the popover itself and white artifacts on the 4 rounded corners.
Please see the screenshot.
What can I do to make the background totally black in interface builder?
I appreciate the answer below but I still can't quite get it to work - here is my code:
// Show the satellite Ephemeris
if ( itemIndex == 1 ) {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
NSLog(#"This is an iPad - Creating popover!");
EphemerisDataView *ephemView = [[EphemerisDataView alloc] init];
UIPopoverController *popOver = [[UIPopoverController alloc] initWithContentViewController:ephemView];
[popOver setPopoverBackgroundViewClass:[DDPopoverBackgroundView class]];
[popOver.popoverBackgroundViewClass setTintColor:[UIColor blackColor]];
CGSize size = CGSizeMake(320, 480); // size of view
popOver.popoverContentSize = size;
[popOver presentPopoverFromRect:self.popOverAnchor.bounds inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
NSLog(#"This is not an iPad - Performing segue...");
// Show the next view
[self performSegueWithIdentifier:#"Ephemeris" sender:self];
}
}
You cannot customize that arrow by IB. You will need a totally customized popover for you. Plenty of them are available on git. But If you want to use default one then it is not possible to customize that arrow as well.
Do it like this:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
NSLog(#"This is an iPad - Creating popover!");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName: #"MainStoryboard_iPad" bundle:[NSBundle mainBundle]];
EphemerisDataView *ephemView = [storyboard instantiateViewControllerWithIdentifier:#"EphemerisDataView"];
UIPopoverController *popOver = [[UIPopoverController alloc] initWithContentViewController:ephemView];
self.customPopoverController = popOver;
[popOver setPopoverBackgroundViewClass:[DDPopoverBackgroundView class]];
[popOver.popoverBackgroundViewClass setTintColor:[UIColor blackColor]];
popOver.delegate = self;
CGSize size = CGSizeMake(320, 480); // size of view
popOver.popoverContentSize = size;
[popOver presentPopoverFromRect:self.popOverAnchor.bounds inView:self.popOverAnchor
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
NSLog(#"This is not an iPad - Performing segue...");
// Show the next view
[self performSegueWithIdentifier:#"Ephemeris" sender:self];
}
I am creating the simple customized camera application.
so. i tried to customize the buttons for flash setting button and capture.
It worked for iPhone4 and iPhone4s... but unfortunately.. it shows the white screen on iPhone3gs.
What's the problem?
#define CAMERA_TRANSFORM_X 1
#define CAMERA_TRANSFORM_Y 1
#define SCREEN_WIDTH 320
#define SCREEN_HEIGTH 480
- (void) showCamera
{
overlay = [[CustomOverlayView alloc]
initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGTH)];
overlay.delegate = self;
self.picker = [[UIImagePickerController alloc] init];
self.picker.delegate = self;
self.picker.navigationBarHidden = YES;
self.picker.toolbarHidden = YES;
self.picker.wantsFullScreenLayout = YES;
self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.picker.showsCameraControls = NO;
self.picker.cameraViewTransform = CGAffineTransformScale(self.picker.cameraViewTransform, CAMERA_TRANSFORM_X, CAMERA_TRANSFORM_Y);
self.picker.cameraOverlayView = overlay;
[self.view addsubview self.picker.view];
}
Call your showCamera method in your root view controller viewDidLoad method, or in its init method if you don't use IB.
You should present your camera controller by using
[self.navigationController presentModalViewContoller:self.picker animated:NO];
I'm building a universal iOS app and the iPad version uses a SplitViewController. In the popover view, I have a UITabBarController with two buttons. When it runs on the iPhone, the TabBar buttons correctly stretch to fill the entire width of the view...
...but on the iPad, in the popover view, the buttons don't stretch to fill the entire width...
I'm creating the UITabBarController programmatically...
InspectionTabBarViewController *inspectionTabBarVC;
InspectionListViewController *inspectionListVC;
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
inspectionListVC = [[InspectionListViewController alloc] initWithSunday:NO];
inspectionListVC.managedObjectContext = self.managedObjectContext;
UINavigationController *calendarNavVC = [[UINavigationController alloc] initWithRootViewController:inspectionListVC];
calendarNavVC.title = #"Calendar";
InspectionMapViewController *mapViewVC = [[InspectionMapViewController alloc] initWithNibName:#"InspectionMapView_iPhone" bundle:nil];
UINavigationController *mapdNavVC = [[UINavigationController alloc] initWithRootViewController:mapViewVC];
mapdNavVC.title = #"Map";
inspectionTabBarVC = [[InspectionTabBarViewController alloc] init];
[inspectionTabBarVC addChildViewController:calendarNavVC];
[inspectionTabBarVC addChildViewController:mapdNavVC];
self.window.rootViewController = inspectionTabBarVC;
}
else
{
inspectionListVC = [[InspectionListViewController alloc] initWithSunday:NO];
UINavigationController *calendarNavVC = [[UINavigationController alloc] initWithRootViewController:inspectionListVC];
calendarNavVC.title = #"Calendar";
InspectionMapViewController *mapViewVC = [[InspectionMapViewController alloc] initWithNibName:#"InspectionMapView_iPad" bundle:nil];
UINavigationController *mapdNavVC = [[UINavigationController alloc] initWithRootViewController:mapViewVC];
mapdNavVC.title = #"Map";
inspectionTabBarVC = [[InspectionTabBarViewController alloc] init];
[inspectionTabBarVC addChildViewController:calendarNavVC];
[inspectionTabBarVC addChildViewController:mapdNavVC];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController_iPad" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = [NSArray arrayWithObjects:inspectionTabBarVC, detailNavigationController, nil];
self.window.rootViewController = self.splitViewController;
inspectionListVC.detailViewController = detailViewController;
inspectionListVC.managedObjectContext = self.managedObjectContext;
detailViewController.detailViewControllerDelegate = inspectionListVC;
}
[self.window makeKeyAndVisible];
I also tried setting the autoResizeMask inside the InspectionTabBarViewController's loadView method using the following statement...
self.tabBar.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth;
...but that didn't work either. How can I get the UITabBar buttons to fill the entire width of of the view?
Thanks so much in advance for your help!
Change UITabBar property itemPositioning to UITabBarItemPositioningFill:
self.tabBar.itemPositioning = UITabBarItemPositioningFill;
Swift version:
tabBar.itemPositioning = .fill
UITabBar itemPositioning reference
This can actually be done by setting the setSelectionIndicatorImage on the tab bar. The buttons will resize to your image's width, regardless of iPhone or iPad.
The problem with this is that it's not dynamic, and every time you add or change the number of items in the tab bar, you'll have to create another image.
A solution is to create the image in code and calculate the width by ({tab bar width}/{# of tabbaritems}).
For example:
Where you create the tab bar:
[[self.tabBarController tabBar] setSelectionIndicatorImage:[self selectionIndicatorImage]];
The image method:
- (UIImage *)selectionIndicatorImage
{
NSUInteger count = [[self.tabBarController viewControllers] count];
CGSize tabBarSize = [[self.tabBarController tabBar] frame].size;
NSUInteger padding = 2;
CGSize buttonSize = CGSizeMake( tabBarSize.width / count, tabBarSize.height );
UIGraphicsBeginImageContext( buttonSize );
CGContextRef c = UIGraphicsGetCurrentContext();
[[UIColor colorWithWhite:0.9 alpha:0.1] setFill];
UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:CGRectMake( padding, padding * 2, buttonSize.width - (padding * 2) , buttonSize.height - ( padding * 2 ) ) cornerRadius:4.0];
[roundedRect fillWithBlendMode: kCGBlendModeNormal alpha:1.0f];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
CGContextRelease( c );
return image;
}
We can not set size for the UITabbarItem dynamically.
In iPhone it sets (Devices Width/no of Tabbaritems)
In iPad it sets with specific width
If you want to create such kind of view, then go with custom buttons which looks like tab bar buttons and add functionality by your code for the same.
I found itemWidth(property of UITabBar) in iOS7.
UITabBar reference
I am looking for some help for a program I am developing. Basically, it contains two views. The first view has a button and a action related to it leads me to my next view where there is a scroll view for three pages ( as in the PageControl sample given by apple.) I am using navigation controller to push the view from the first view to the second view. But on pushing I am not able to scroll the page or using page control or anything. It just comes a normal view. The code is same as pageControl code and it works fine as a separate module. But when I want to integrate this pageControl code with a first view and a click button it doesn't work. Please help.
//this function is an action set against a button in the rootviewcontroller.
-(IBAction) viewScrollPages:(id)sender{
UIViewController *controller = [[MyViewController alloc] initWithPageNumber:0];
[self.navigationController pushViewController:controller animated:NO];
[controller release];
}
- (id)initWithPageNumber:(int)page {
if (self = [super initWithNibName:#"MyViewController" bundle:nil]) {
pageNumber = page;
}
return self;
}
- (void)viewDidLoad {
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < kNumberOfPages; i++) {
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
// a page is the width of the scroll view
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height);
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.delegate = self;
pageControl.numberOfPages = kNumberOfPages;
pageControl.currentPage = 0;
// pages are created on demand
// load the visible page
// load the page on either side to avoid flashes when the user starts scrolling
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
pageNumberLabel.text = [NSString stringWithFormat:#"Page %d", pageNumber + 1];
self.view.backgroundColor = [MyViewController pageControlColorWithIndex:pageNumber];
[super viewDidLoad];
}
It sounds like your pushing a normal view that is a subview of the scrollview instead of pushing the scrollview itself.
I'm trying to do the following:
alt text http://img101.imageshack.us/img101/7396/33959221.png
I need to do a lot of custom things, so I subclassed everything.
alt text http://img248.imageshack.us/img248/4201/49422483.png
I'm having issues with autoresize and positioning. For instance the UIToolBar is not at the correct position.
So here is the question:
If you don't use UITableViewController or any other Controller, that takes care of all the positioning and sizing, then you have to do it yourself.
Can someone someone tell me how this works? What do I need to understand?
---- UPDATE:
My custom goals are actually not that important as my question is actually about something else. But OK. So all "elements" like the TableView, the Toolbar and the TabBar will have custom backgrounds and use custom buttons. The TableView will be GroupedStyle and the groups can be collapsed.
My question is how do I have to structure my code especially regarding positioning and autoresizing in order to achieve what you can see in picture #1.
This is how it's structured right now:
Application Delegate:
- (void) loadView {
RootViewController *rootView = [[RootViewController alloc] init];
[window addSubview:rootView.view];
[window makeKeyAndVisible];
RootViewController:
- (void) loadView {
self.theView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.theView.autoresizesSubviews = YES;
self.theView.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
self.view = self.theView;
ChildViewController *childView = [[ChildViewController alloc] init];
[self.view addSubview:childView.view];
ChildViewController:
- (void) loadView {
self.theView = [[UIView alloc] init];
self.view = self.theView;
}
- (void) viewDidLoad {
self.view.frame = [[UIScreen mainScreen] bounds];
CGRect toolbarBounds = self.theToolbar.bounds;
CGRect viewBounds = self.view.bounds;
CGRect tableViewBounds = CGRectMake(0, CGRectGetHeight(toolbarBounds), CGRectGetWidth(viewBounds), CGRectGetHeight(viewBounds) - CGRectGetHeight(toolbarBounds));
self.view.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
self.theTableView = [[MyTableView alloc] initWithFrame:tableViewBounds
style:UITableViewStyleGrouped
parent:self];
[self.view addSubview:self.theToolbar];
[self.view addSubview:self.theTableView];
}
MyToolBar:
- (id)initWithParent:(id)theParent {
if ((self = [self init])) {
self.parent = theParent;
CGRect rectArea = CGRectMake(0, 0, CGRectGetWidth([[[self parent] view] bounds]), 44);
[self setFrame:rectArea];
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self loadButtons];
}
return self;
}
So this is how the positioning is structured at the moment (messy). It actually works, BUT I have a ModalView which is handled by the ChildViewController. When I have the iPad in Portrait view and I pop up the modal view and dismiss it, then everything works. But when I do the same on Landscape view it rotates the hole view... the ChildViewController by 90 degrees when dismissing the modal view. Very strange. When I load directly ChildViewController in my AppDelegate, then again everything works fine.
You're missing the UIViewAutoresizingFlexibleBottomMargin option in the autoresize mask of your toolbar, for instance.