Root view controller is built in code - Wont resize for iPad - objective-c

Im trying to convert my iphone app to ipad, all good until my root view controller. Its been built in code and no matter what I do I cant resize it/centre it. I have no nib for my Home page. Autoresize masks doesn't do anything, adding an iPad nib does nothing despite best efforts but continue to present the iphone screen in top left, and using if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) loads a a blank black iPad screen. I really dont know what to to now. If I set my screen elements to initWithFrame:[[UIScreen mainScreen] bounds]]; the artwork is distorted as its overstretched.
// Create the main view
UIView *mainView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
mainView.backgroundColor = [UIColor blackColor];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
UIImageView *textureBg = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 768.0f, 1024.0f)];
textureBg.image = [UIImage imageNamed:#"BgTexture"];
[textureBg addSubview:textureBg];
}
else {
// Add textured background
UIImageView *textureBg = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320.0f, 1024.0f)];
textureBg.image = [UIImage imageNamed:#"BgTexture"];
[textureBg addSubview:textureBg];
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
UIImageView *clipBg = [[UIImageView alloc] initWithFrame:CGRectMake(7.0f, 6.0f, 605.0f, 865.0f )];
clipBg.image = [UIImage imageNamed:#"BgHomeNew2"];
clipBg.userInteractionEnabled = YES;
}
else {
// Add clipboard background
UIImageView *clipBg = [[UIImageView alloc] initWithFrame:CGRectMake(7.0f, 6.0f, 305.0f, 465.0f )];
clipBg.image = [UIImage imageNamed:#"BgHomeNew2"];
clipBg.userInteractionEnabled = YES;
//[clipBg setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin )];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// Add about button to clipbg
UIButton *aboutButton = [UIButton buttonWithType:UIButtonTypeCustom];
aboutButton.frame = CGRectMake(240.0f, 90.0f, 31.0f, 33.0f);
[aboutButton setImage:[UIImage imageNamed:#"LabelButton"] forState:UIControlStateNormal];
[aboutButton addTarget:self action:#selector(aboutButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[aboutButton addSubview:aboutButton];
}
else {
// Add about button to clipbg
UIButton *aboutButton = [UIButton buttonWithType:UIButtonTypeCustom];
aboutButton.frame = CGRectMake(240.0f, 90.0f, 31.0f, 33.0f);
[aboutButton setImage:[UIImage imageNamed:#"LabelButton"] forState:UIControlStateNormal];
[aboutButton addTarget:self action:#selector(aboutButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[aboutButton addSubview:aboutButton];
}
How do I make an ipad view, for a universal app, where the root view controller is built in code? Im even open to the idea of simply centering the iphone screen in the middle of the ipad screen but as autoresing wont work its just stuck in the top left. This would be 2 mins in IB!
To summarise why wont the following code move the image to the center of the iPad screen?
UIImageView *clipBg = [[UIImageView alloc] initWithFrame:CGRectMake(7.0f, 6.0f, 305.0f, 465.0f )];
clipBg.image = [UIImage imageNamed:#"BgHomeNew2"];
clipBg.userInteractionEnabled = YES;
[clipBg setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin)];
EDIT
Really dont know what im missing here, been on this a whole day now, Cant seem to add a xib retrospectively to an iphone screen built in code, so I will settle for centring objects in the middle of the screen when ipad is used rather than stuck in the top left all the time. That dosent work either.

Ok sorted it
Ive finally maged to add xibs now so I can adjust as necessary, I couldn't initialise the xibs before because I had missed this line of code in my rootview contoller
- (id)init
{
[[NSBundle mainBundle] loadNibNamed:#"ICHomeController" owner:self options:nil];

Related

Display issue with customized UINavigationBar

I'm currently encountering an issue with the customized navigation bar of my app, especially on iPad Pro and iPad.
I've extended UINavigationBar to create a personalized top bar.
I'm only using Objectiv-C, and here is the initialization function :
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:(NSCoder *)aDecoder];
if (self)
{
[self setTranslucent:FALSE];
UIImageView *mylogo = [[UIImageView alloc] initWithImage:[self imageWithImage:[UIImage imageNamed:#"minilogo.png"] scaledToSize:CGSizeMake(200, 25)]];
[self.topItem setTitleView:mylogo];
menuButton = [UIButton buttonWithType:UIButtonTypeCustom];
menuButton.frame = CGRectMake(0, 0, 44, 44);
[menuButton setImage:[UIImage imageNamed:#"menuButton.png"] forState:UIControlStateNormal];
[menuButton setContentMode:UIViewContentModeCenter];
CALayer *menuBorder = [CALayer layer];
[menuBorder setFrame:CGRectMake(43, 0, 1, 44)];
[menuBorder setBackgroundColor:[[UIColor blackColor] CGColor]];
[menuButton.layer addSublayer:menuBorder];
[self.topItem setLeftBarButtonItem: [[UIBarButtonItem alloc] initWithCustomView:menuButton]];
searchButton = [UIButton buttonWithType:UIButtonTypeCustom];
searchButton.frame = CGRectMake(0, 0, 44, 44);
UIImage *searchImage = [self imageWithImage:[UIImage imageNamed:#"boutonRecherche.png"] scaledToSize:CGSizeMake(44, 44)];
[searchButton setBackgroundImage:searchImage forState:UIControlStateNormal];
[searchButton setContentMode:UIViewContentModeCenter];
CALayer *searchBorder = [CALayer layer];
[searchBorder setFrame:CGRectMake(0, 0, 1, 44)];
[searchBorder setBackgroundColor:[[UIColor blackColor] CGColor]];
[searchButton.layer addSublayer:searchBorder];
[self.topItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithCustomView:searchButton]];
if (#available(iOS 15.0, *))
{
UINavigationBarAppearance *navBarApparance = [[UINavigationBarAppearance alloc] init];
[navBarApparance setBackgroundImage:[UIImage imageNamed:#"fd_entete.png"]];
[self setStandardAppearance:navBarApparance];
[self setCompactAppearance:navBarApparance];
[self setScrollEdgeAppearance:navBarApparance];
}
else
{
[self setOpaque:YES];
[self setBackgroundImage:[UIImage imageNamed:#"fd_entete.png"] forBarMetrics:UIBarMetricsDefault];
}
}
return self;
}
My navigation bar is added to the view using the storyboard and I specifying its class name in the identity inspector tab.
I've set layout constraints so the content of my view is right under this navigation bar.
Here is a sample with a simple controller having the navigation bar and a webview beneath :
The issue I'm having only concerns iPads. Here is a screenshot of how it looks like on an iPad pro :
(the grey rect is just to illustrate that I've shorten the screenshot)
But surprisingly, the navigation bar render correctly if the view beneath is a UITableView, but it still have the border issue for the buttons - understand here that the button border is missing some pixels on top and bottom :
(it is also how the nav bar looks like on an iPad for any view controller)
In comparison, I don't have the issue on iPhones :
Any help is appreciated.

UINavigationItem rightbarbuttonitem not displaying

As my title, I have went through several websites and failed to achieve the result. However, I managed to add an image on the navigation bar successfully. These are two problems I'm facing currently, both are under UINavigationBar section.
1. Unable to display the rightbarbutton
2. Unable to hide the back arrow "<"
MasterViewController.m
//Back Button
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backBtnImage = [UIImage imageNamed:#"sidemenu.png"];
[backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal];
backBtn.frame = CGRectMake(0, 0, 54, 30);
//Rightbarbutton
UIButton *infoButton = (UIButton *) [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon_info.png"]];
UIBarButtonItem *infoButtonItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton];
self.navigationItem.rightBarButtonItem = infoButtonItem;
//Image (Working and displaying)
UIImage *image = [UIImage imageNamed: #"icon_image.png"];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(245, 0, 30, 42)];
[imageView setImage:image];
[self.navigationController.navigationBar addSubview:imageView];
I think you should initialize you rightItem's content as an UIButton and not a cast from ImageView to UIButton... so the same procedure you are doing for the back item..
This is your UINavigationItem+AtAdditions.h file
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, ATNavigationItemButtonSide) {
ATNavigationItemButtonSideRight,
ATNavigationItemButtonSideLeft
};
#interface UINavigationItem(ATAdditions)
// This method adds an image-only button to the requested size (right or left) of the current navigation item, the image can't be tapped
- (void)addColorfulImage:(NSString*)imageName toSide:(ATNavigationItemButtonSide)side;
#end
This is your UINavigationItem+AtAdditions.m file
#import "UINavigationItem+ATAdditions.h"
#implementation UINavigationItem(ATAdditions)
- (void)addColorfulImage:(NSString*)imageName toSide:(ATNavigationItemButtonSide)side {
// Create a button with the required image on it
UIImage *image = [UIImage imageNamed:imageName];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.bounds = CGRectMake(0, 0, image.size.width, image.size.height );
[button setImage:image forState:UIControlStateNormal];
// Stop the events (it's an image only)
button.userInteractionEnabled = NO;
// Add the button to the navigation item
if (side == ATNavigationItemButtonSideLeft) {
self.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
}
else if (side == ATNavigationItemButtonSideRight) {
self.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
}
}
#end
Later you can import the .h file and use it on the navigation item in your view controller.

UINavigationBar - change UIBarButtonItem positions

I am using a UINavigationController and its bar within my app.
Now I want to change the leftBarButtonItem and rightBarButtonItem positions.
I want them to be on a different x and y position having a custom witdth and height.
But the problem is, that changing the frame does not change anything with the barButtonItem. I do not now why, but the frame always gets resetted to its original coordinates.
Here is my code which I call in viewWillAppear:
UINavigationItem *navItem = [[self.navigationBar items] lastObject];
UIView *rightview = [[UIView alloc] initWithFrame:CGRectMake(0,0,66,30)];
rightview.backgroundColor = [UIColor blueColor];
//add custom view
UIBarButtonItem *search = [[UIBarButtonItem alloc] initWithCustomView:rightview];
navItem.leftBarButtonItem = search;
The view is not starting at 0/0, the x position for example is at 5px insetead of 0.
Any suggestions on how to solve this issue?
This worked for me for the leftBarButtonItem:
If you want the UIBarButtonItem to show exactly at position (0, 0), you can create a UIButton, sets its frame to (-5, 0, width, height), assuming that the offet of a left barbutton item is (5, 0), and place that in a UIView that you set as leftBarButtonItem.
#import "UINavigationItem+CSAButtons.h"
#implementation UINavigationItem (CSAButtons)
- (void) makeLeftBarButtonWithTarget:(id)target action:(SEL)action {
UIImage * imageNormal = [UIImage imageNamed:#"normal.png"];
UIImage * imageHighlighted = [UIImage imageNamed:#"highlighted.png"];
UIImage * imageDisabled = [UIImage imageNamed:#"disabled.png"];
// create your button
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.exclusiveTouch = YES;
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:imageNormal forState:UIControlStateNormal];
[button setBackgroundImage:imageHighlighted forState:UIControlStateHighlighted];
[button setBackgroundImage:imageDisabled forState:UIControlStateDisabled];
// set the frame of the button (better to grab actual offset of leftbarbuttonitem instead of magic numbers)
button.frame = CGRectMake(-5.0, 0.0, imageNormal.size.width, imageNormal.size.height);
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, imageNormal.size.width, imageNormal.size.height)];
[view addSubview:button];
// set the barbuttonitem to be the view
UIBarButtonItem * barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:view];
self.leftBarButtonItem = barButtonItem;
}
I dont think you have the ability to move a UIBarButtonItem but you might be able to achieve the same effect by adding that UIView element as a subview to the navigationBar (or navItem). You'll need to play with it a bit. It should allow for much more flexibility.
hope this helps.

UINavigationController rightbarbuttonitem not showing

after going through the questions related to UINavigationController item i came to post my exact problem ..
firstly i am not add a UINavigationController in MainWindow.xib i created and adding UINavigationController in AppDelegate file
after that in a UIViewController (not in rootViewController) class I have to add a rightbarbutton of Done type I am
adding it in a searchbarDelegate Method showing as bold:-
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
//This method is called again when the user clicks back from teh detail view.
//So the overlay is displayed on the results, which is something we do not want to happen.
if(exhibDataObj.searching)
return;
//Add the overlay view.
if(ovController == nil)
ovController = [[OverlayViewController alloc] initWithNibName:#"OverlayView" bundle:[NSBundle mainBundle]];
CGFloat yaxis = self.navigationController.navigationBar.frame.size.height;
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
//Parameters x = origion on x-axis, y = origon on y-axis.
CGRect frame = CGRectMake(0, yaxis, width, height);
ovController.view.frame = frame;
ovController.view.backgroundColor = [UIColor grayColor];
ovController.view.alpha = 0.5;
ovController.rvController = self;
[self.theTableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
exhibDataObj.searching = true;
letUserSelectRow = NO;
self.theTableView.scrollEnabled = NO;
//Add the done button.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self action:#selector(doneSearching_Clicked:)];
}
but this never works .
Any help will be more appreciable.
I've tested your code real quick and it seems to be working fine for me, however, I've had the same problem once back then it turned out I was setting the rightBarButtonItem to nil in my viewDidLoad method after setting it to a button. you should make sure your not making the same mistake somehow.
However if that does not work for you you can always try setting a custom button to it:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 5, 30, 30)];
button.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"done.png"]];
[button addTarget:self action:#selector(doneButtonClicked) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationController.visibleViewController.navigationItem.rightBarButtonItem = customItem;

How to call PopOver Controller from UITableViewCell.accessoryView?

First I would like to say that I'm really new to ipad/ipod/iphone development, and to objective-c too.
With that being said, I'm trying to develop a small application targeting the iPad, using Xcode and IB, basically, I have a table, for each UITableViewCell in the table, I added to the accessoryView a button that contains an image.
Here is the code:
UIImage *img = [UIImage imageNamed:#"myimage.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, img.size.width, img.size.height);
button.frame = frame; // match the button's size with the image size
[button setBackgroundImage:img forState:UIControlStateNormal];
// set the button's target to this table view controller so we can interpret touch events and map that to a NSIndexSet
[button addTarget:self action:#selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;
So far, so good, now the problem is that I want a PopOver control to appear when a user taps the button on the accessoryView of a cell.
I tried this on the "accessoryButtonTappedForRowWithIndexPath" of the tableView:
UITableViewCell *cell = [myTable cellForRowAtIndexPath:indexPath];
UIButton *button = (UIButton *)cell.accessoryView;
//customViewController is the controller of the view that I want to be displayed by the PopOver controller
customViewController = [[CustomViewController alloc]init];
popOverController = [[UIPopoverController alloc]
initWithContentViewController: customViewController];
popOverController.popoverContentSize = CGSizeMake(147, 122);
CGRect rect = button.frame;
[popOverController presentPopoverFromRect:rect inView:cell.accessoryView
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
The problem with this code is that it shows the Popover at the top of the application View, while debugging I saw the values of "rect" and they are:
x = 267
y = 13
so I think it is pretty obvious why the PopOver is being displayed so up on the view, so my question is, how can I get the correct values for the PopOver to appear just below the button on the accessoryView of the cell?
Also, as you can see, I'm telling it to use the "cell.accessoryView" for the "inView:" attribute, is that okay?
Try using button.bounds instead of button.frame since the rect is relative to the inView.
Also note that if the cell is near the bottom of the screen, the popover may not appear at the right size because you are forcing the arrow in the Up direction. You should either handle this manually or just use Any.
[popOverController presentPopoverFromRect:rect inView:cell.accessoryView
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
Changing inView:cell.accessoryView to inView:cell
here's for swift:
let cell = tableView.cellForRowAtIndexPath(indexPath)
let rect = tableView.convertRect(tableView.rectForRowAtIndexPath(indexPath), toView: tableView)
var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("loadZone") as! UIViewController
var nav = UINavigationController(rootViewController: popoverContent)
nav.modalPresentationStyle = UIModalPresentationStyle.Popover
var popover = nav.popoverPresentationController
popoverContent.preferredContentSize = CGSizeMake(100,200)
popover!.sourceView = tableView
popover!.sourceRect = rect
self.presentViewController(nav, animated: true, completion: nil)