Dismissing MFMailComposeViewController causes upward shift - ios

I've ran into an issue when dismissing the MFMailComposeViewController and returning to a shifted screen in iOS7. The method below has worked on iOS6 without shifting the screen upwards of about 25-30. Altering my[[UIScreen mainScreen] applicationFrame]] to using auto resize isn't fixing my issue as suggested in another question of downward shifting.
#import "RootViewController.h"
#implementation RootViewController
- (void)loadView {
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
self.view.backgroundColor = [UIColor whiteColor];
navBar = [[UINavigationBar alloc] init];
navBar.frame = CGRectMake(0, 0, self.view.frame.size.width, 44);
UINavigationItem *navItem = [[[UINavigationItem alloc] initWithTitle:#"iShift"] autorelease];
UIBarButtonItem *mail = [[[UIBarButtonItem alloc] initWithTitle:#"Email" style:UIBarButtonItemStylePlain target:self action:#selector(sendMail)] autorelease];
navItem.rightBarButtonItem = mail;
navBar.barStyle = UIBarStyleDefault;
navBar.items = [NSArray arrayWithObject:navItem];
[self.view addSubview:navBar];
}
- (void)sendMail {
MFMailComposeViewController *compose = [[MFMailComposeViewController alloc] init];
compose.mailComposeDelegate = self;
if ([MFMailComposeViewController canSendMail]){
NSArray *toRecipients = [NSArray arrayWithObjects:#"sample#gmail.com", nil];
[compose setToRecipients:toRecipients];
[compose setSubject:#"Test Email"];
[compose setMessageBody:#"Device: \niOS Version: \nProblem: \n\nSuggestions: \n" isHTML:NO];
[self presentModalViewController:compose animated:YES];
}
[compose release];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self dismissModalViewControllerAnimated:YES];
}
#end

I've managed to solve this issue in what seems to be pretty dirty by changing [[UIScreen mainScreen] applicationFrame]] to [[UIScreen mainScreen] bounds]] and padding the navbar position by 20pts resulting in the following code. If someone can point out a problem with this I'm open to suggestions. (With a tableview it's y position is also padded by 20pts)
#import "RootViewController.h"
#implementation RootViewController
- (void)loadView {
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.view.backgroundColor = [UIColor whiteColor];
navBar = [[UINavigationBar alloc] init];
navBar.frame = CGRectMake(0, 20, self.view.frame.size.width, 44);
UINavigationItem *navItem = [[[UINavigationItem alloc] initWithTitle:#"iShift"] autorelease];
UIBarButtonItem *mail = [[[UIBarButtonItem alloc] initWithTitle:#"Email" style:UIBarButtonItemStylePlain target:self action:#selector(sendMail)] autorelease];
navItem.rightBarButtonItem = mail;
navBar.barStyle = UIBarStyleDefault;
navBar.items = [NSArray arrayWithObject:navItem];
[self.view addSubview:navBar];
}
- (void)sendMail {
MFMailComposeViewController *compose = [[MFMailComposeViewController alloc] init];
compose.mailComposeDelegate = self;
if ([MFMailComposeViewController canSendMail]){
NSArray *toRecipients = [NSArray arrayWithObjects:#"sample#gmail.com", nil];
[compose setToRecipients:toRecipients];
[compose setSubject:#"Test Email"];
[compose setMessageBody:#"Device: \niOS Version: \nProblem: \n\nSuggestions: \n" isHTML:NO];
[self presentModalViewController:compose animated:YES];
}
[compose release];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self dismissModalViewControllerAnimated:YES];
}
#end

Related

Pushing UITabBarController into UInavigationController

I have a UINavigationController as the root view controller of an app.
At some point I need to push a UITabController with specific tabs.
Up to this point it all works.
However in the tab view controllers I can't access the UINavigationController navBar (to change title, tint, etc).
Here is how I push it:
SCTabController *TabController = [[SCTabController alloc] init];
[self.navigationController pushViewController:TabController animated:YES];
SCTabController is a subclass of UITabController with the following viewDidLoadMethod:
- (void)viewDidLoad {
[super viewDidLoad];
UIViewController *view1 = [[UIViewController alloc] init];
UIViewController *view2 = [[UIViewController alloc] init];
UIViewController *view3 = [[UIViewController alloc] init];
UIViewController *view4 = [[UIViewController alloc] init];
NSMutableArray *tabViewControllers = [[NSMutableArray alloc] init];
[tabViewControllers addObject:view1];
[tabViewControllers addObject:view2];
[tabViewControllers addObject:view3];
[tabViewControllers addObject:view4];
[self setViewControllers:tabViewControllers];
//can't set this until after its added to the tab bar
bankHomeViewController.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"Title1"
image:nil
tag:1];
view2.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"Title2"
image:nil
tag:2];
view3.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"Title3"
image:nil
tag:3];
view4.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"Title4"
image:nil
tag:4];
In my project I have done so :
add UITabBarControllerDelegate
#interface SCTabController : UITabBarController<UITabBarControllerDelegate>
#end
then add below code in viewDidLoad in SCTabController.m
self.delegate = self;
implement UITabBarControllerDelegate didSelectViewController in SCTabController.m
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
//Write your code here
//NSLog(#"%lu", (unsigned long)self.selectedIndex);
UILabel *functionTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 190, 50)];
[functionTitleLabel setTextAlignment:NSTextAlignmentCenter];
switch (self.selectedIndex) {
case 0:
[functionTitleLabel setText:#"title1"];
break;
case 1:
[functionTitleLabel setText:#"title2"];
break;
case 2:
[functionTitleLabel setText:#"title3"];
break;
default:
[functionTitleLabel setText:#"title4"];
break;
}
self.navigationItem.titleView = functionTitleLabel;
}

Custom Navigation Transitions on iOS 7, how to manage the keyboard?

TabBarController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
PlaylistViewController *playlistViewController = [[PlaylistViewController alloc] init];
UIViewController *otherViewController = [[UIViewController alloc] init];
UINavigationController *playlistNavigationController = [[UINavigationController alloc] initWithRootViewController:playlistViewController];
playlistNavigationController.delegate = self;
self.viewControllers = #[playlistNavigationController, otherViewController];
playlistNavigationController.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemDownloads tag:kTabBarTagPlaylist];
playlistNavigationController.tabBarItem.title = #"Playlist";
otherViewController.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemMore tag:kTabBarTagOther];
playlistNavigationController.navigationBar.tintColor = [UIColor redColor];
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
if (operation == UINavigationControllerOperationPush) return [[FadeTransition alloc] init];
else if (operation == UINavigationControllerOperationPop) return [[SlideTransition alloc] init];
return nil;
}
PlaylistViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor redColor];
UIBarButtonItem *storeBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Store"
style:UIBarButtonItemStylePlain
target:self
action:#selector(test)];
self.navigationItem.leftBarButtonItem = storeBarButtonItem;
UIBarButtonItem *currentlyPlayingButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Now playing"
style:UIBarButtonItemStylePlain
target:self
action:#selector(test)];
self.navigationItem.rightBarButtonItem = currentlyPlayingButtonItem;
self.navigationItem.title = #"Playlist";
self.playlistTableViewController = [[PlaylistTableViewController alloc] initWithStyle:UITableViewStylePlain];
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
searchBar.placeholder = #"Search";
searchBar.delegate = self;
self.playlistTableViewController.tableView.tableHeaderView = searchBar;
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchController.delegate = self;
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
[self addChildViewController:self.playlistTableViewController];
[self.view addSubview:self.playlistTableViewController.view];
self.playlistTableViewController.view.frame = self.view.bounds;
self.playlistTableViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
[self.playlistTableViewController didMoveToParentViewController:self];
}
FadeTransition.m
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
return 0.5;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
/* view controllers */
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
/* views */
UIView *containerView = [transitionContext containerView];
[containerView addSubview:fromVC.view];
[containerView addSubview:toVC.view];
/* settings */
toVC.view.alpha = 0.0f; /* not visible at start */
[UIView animateWithDuration:[self transitionDuration:transitionContext]
delay:0
options:UIViewAnimationOptionTransitionNone
animations:^{
toVC.view.alpha = 1.0f; /* 100% visible at the end */
}
completion:^(BOOL finished) {
[fromVC.view removeFromSuperview];
[transitionContext completeTransition:YES];
}];
}
This is how it looks like:
When I touch one of the results, a new UIView gets pushed and animated by FadeTransition.
The keyboard automatically gets slided down, but I need to leave the keyboard opened (it should stay behind), how can I do it?

Why is the Navigation Bar on top of the UIViewWeb? (Beginner in OBJ-C)

I have a small problem.
Basically, I have a UIWebView that is located under the navigation bar, so I need to scroll down to view the contents, and it scrolls up at the end. How Do I make the UIWebView appear right below the navigation bar?
#import "RootViewController.h"
#implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
webview=[[UIWebView alloc]initWithFrame:self.view.bounds];
NSString *url=#"http://localhost/";
NSURL *nsurl=[NSURL URLWithString:url];
NSURLRequest *nsrequest=[NSURLRequest requestWithURL:nsurl];
[webview loadRequest:nsrequest];
[self.view addSubview:webview];
navBar = [[UINavigationBar alloc] init];
navBar.frame = CGRectMake(0, 0, self.view.frame.size.width, 44);
UINavigationItem*navItem = [[[UINavigationItem alloc] initWithTitle:#"iPaint"] autorelease];
UIBarButtonItem*leftButton = [[[UIBarButtonItem alloc] initWithTitle:#"Left" style:UIBarButtonItemStylePlain target:self action:#selector(rightButtonPressed)] autorelease];
navItem.leftBarButtonItem = leftButton;
UIBarButtonItem*rightButton = [[[UIBarButtonItem alloc] initWithTitle:#"Right" style:UIBarButtonItemStylePlain target:self action:#selector(rightButtonPressed)] autorelease];
navItem.rightBarButtonItem = rightButton;
navBar.barStyle = UIBarStyleDefault;
navBar.items = [NSArray arrayWithObject:navItem];
[self.view addSubview:navBar];
}
-(void)leftButtonPressed{
//Code Here
}
-(void)rightButtonPressed{
//Code Here
}
#end
main.mm Code:
int main(int argc, char **argv) {
NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
int ret = UIApplicationMain(argc, argv, #"comvlad1kwebApplication", #"comvlad1kwebApplication");
[p drain];
return ret;
}
// vim:ft=objc
I am using Theos, so I don't have an Xcode, therefore I need to manually do it.
Thank you.
EDIT: Here is a link to a screenshot: http://i.imgur.com/aQ4yuyp.png
The main issue is that you are creating a UINavigationBar manually. What you want is to be using a UINavigationController, which is a view controller that manages a stack of other view controllers and navigation between them. In your application delegate, you probably have code that looks something like this:
// Assuming that your UIApplication Delegate has a _viewController ivar which is properly memory-managed.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_viewController = [[RootViewController alloc] init];
[_window addSubview:_viewController.view];
[_window makeKeyAndVisible];
}
That snippet of code creates an instance of RootViewController and sets it to be the main view controller in the application. What you want instead is to put a RootViewController inside a UINavigationController, like this:
// Assuming that your UIApplication Delegate has a _viewController ivar which is properly memory-managed.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_viewController = [[RootViewController alloc] init];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:_viewController] autorelease];
[_window addSubview:navController.view];
[_window makeKeyAndVisible];
}
Once you've created a UINavigationController subclass, you should remove the UINavigationBar from your RootViewController, as it is no longer necessary.
You shouldn't set frame of views, based on controller's view's frame in viewDidLoad method. Set frame of webView and NavigationBar on viewWillAppear.
Also, probably you would want to use UINAvigationController, instead of adding UINavigationBar manually
#import "RootViewController.h"
#implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
webview=[[UIWebView alloc]initWithFrame:CGrectZero];
NSString *url=#"http://localhost/";
NSURL *nsurl=[NSURL URLWithString:url];
NSURLRequest *nsrequest=[NSURLRequest requestWithURL:nsurl];
[webview loadRequest:nsrequest];
[self.view addSubview:webview];
navBar = [[UINavigationBar alloc] init];
UINavigationItem*navItem = [[[UINavigationItem alloc] initWithTitle:#"iPaint"] autorelease];
UIBarButtonItem*leftButton = [[[UIBarButtonItem alloc] initWithTitle:#"Left" style:UIBarButtonItemStylePlain target:self action:#selector(rightButtonPressed)] autorelease];
navItem.leftBarButtonItem = leftButton;
UIBarButtonItem*rightButton = [[[UIBarButtonItem alloc] initWithTitle:#"Right" style:UIBarButtonItemStylePlain target:self action:#selector(rightButtonPressed)] autorelease];
navItem.rightBarButtonItem = rightButton;
navBar.barStyle = UIBarStyleDefault;
navBar.items = [NSArray arrayWithObject:navItem];
[self.view addSubview:navBar];
}
- (void)viewWillAppear:(BOOL)animated{
navBar.frame = CGRectMake(0, 0, self.view.frame.size.width, 44);
CGRect r = self.view.bounds;
r.origin.y = CGRectGetMaxY(navBar.frame);
r.size.width = r.size.width - CGRectGetMaxY(navBar.frame);
[webView setFrame:r];
}
-(void)leftButtonPressed{
//Code Here
}
-(void)rightButtonPressed{
//Code Here
}
#end

IOS UINavigationController, pushViewController not working

Good evening,
I currently have two UIViewControllers. My appDelegate looks like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
struct CGRect rect = [[UIScreen mainScreen] bounds];
rect.origin.x = rect.origin.y = 0.0f;
_viewController = [[sandboxViewController alloc] init];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:_viewController];
_window = [[UIWindow alloc] initWithFrame:rect];
[_window makeKeyAndVisible];
[_window addSubview:nc.view];
return YES;
}
The viewController looks like this:
- (void)loadView {
self.view = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 480.0f)];
self.view.backgroundColor = [UIColor whiteColor];
self.navigationItem.title = #"Master View";
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[infoButton addTarget:self action:#selector(switchView:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton];
}
- (void)switchView:(id)obj {
if(![self navigationController])
NSLog(#"navigationController IS NIL!!!");
if(!_secondView)
_secondView = [[secondViewController alloc] init];
[self.navigationController pushViewController:_secondView animated:YES];
}
By clicking on the info button, that was added to the right side on the navigation bar, I want to switch to the secondView. This, however, is not happening because navigationController logs as nil ! What am I missing here?
Any help is truly appreciated!
You don't have to create the window, it should already exist.
//_window = [[UIWindow alloc] initWithFrame:rect]; //remove this line
[self.window makeKeyAndVisible]; //use the ivar
[self.window addSubview:nc.view];

Toolbar + Navigation Bar + Segmented Control?

I'm trying to find a way to layout an application that includes a tab bar on the bottom, a navigation bar on the top, and a row of buttons on the navigation bar that switches views (on the first tab).
I've drawn a very rough sketch (sorry!), but I hope it illustrates the intent.
On the bottom, there are two tabs (tab1, and tab2).
When Tab1 is selected, the navigation bar will have 3 buttons that will show different views (tab1_1, tab1_2, tab1_3).
When Tab2 is selected, the navigation bar won't show any buttons, but rather some simple text.
At this point, I have the following scheme in my application delegate's didFinishLaunchingWithOptions:
UIViewController *viewController1 = [[Tab1_ViewController alloc] initWithNibName:#"Tab1_ViewController" bundle:nil];
UIViewController *viewController2 = [[Tab2_ViewController alloc] initWithNibName:#"Tab2_ViewController" bundle:nil];
tab1NavController = [[UINavigationController alloc] initWithRootViewController:viewController1];
tab2NavController = [[UINavigationController alloc] initWithRootViewController:viewController2];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:tab1NavController, tab2NavController, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
I was wondering if I need to redo how I'm doing things in order to achieve the layout as in the picture.
Any help would be appreciated, thank you!
I have done this for my current project...i hope this will help you....
At first take UITabbarController at your first viewController [first sketch you have given]
For your first view use this code....
- (void)viewDidLoad {
[super viewDidLoad];
dashBoardView = [[DashboardViewController alloc] initWithNibName:#"DashboardViewController" bundle:nil];
dashBoardView.title = #"dashBoardView";
UINavigationController *mydashboarController = [[[UINavigationController alloc] initWithRootViewController:dashBoardView] autorelease];
mydashboarController.navigationBar.barStyle = UIBarStyleBlack;
[listOfViewControllers addObject:mydashboarController];
[dashBoardView release];
ordersView = [[OrdersViewController alloc] initWithNibName:#"OrdersViewController" bundle:nil];
ordersView.title = #"ordersView";
UINavigationController *myorderController = [[[UINavigationController alloc] initWithRootViewController:ordersView] autorelease];
myorderController.navigationBar.barStyle = UIBarStyleBlack;
[listOfViewControllers addObject:myorderController];
[ordersView release];
orderList = [[OrderListViewController alloc] initWithNibName:#"OrderListViewController" bundle:nil];
orderList.title = #"orderList";
UINavigationController *myorderListController = [[[UINavigationController alloc] initWithRootViewController:orderList] autorelease];
myorderListController.navigationBar.barStyle = UIBarStyleBlack;
[listOfViewControllers addObject:myorderListController];
[orderList release];
productView = [[ProductViewController alloc] initWithNibName:#"ProductViewController" bundle:nil];
productView.title = #"productView";
UINavigationController *myproductController = [[[UINavigationController alloc] initWithRootViewController:productView] autorelease];
[listOfViewControllers addObject:myproductController];
[productView release];
[self.tabBarController setViewControllers:listOfViewControllers animated:YES];
NSArray *segmentTextContent = [NSArray arrayWithObjects:NSLocalizedString(#"Dashboard", #""),NSLocalizedString(#"Order", #""),
NSLocalizedString(#"Product", #""),NSLocalizedString(#"More", #""),
nil];
UISegmentedControl* segmentedControl = [[UISegmentedControl alloc] initWithItems:segmentTextContent];
segmentedControl.selectedSegmentIndex = 0;
segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.frame = CGRectMake(0, 0, 400, 40);
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
//defaultTintColor = [segmentedControl.tintColor retain]; // keep track of this for later
segmentedControl.tintColor = [UIColor colorWithHue:8.0 saturation:8.0 brightness:8.0 alpha:1.0];
segmentedControl.alpha = 0.8;
self.navigationItem.titleView = segmentedControl;
[segmentedControl release];
}
If it is not clear to you then please knock...

Resources