Very odd iOS orientation issue with Three20 - ios

This is amongst the oddest issues with iOS development I have ever seen. I'm relatively new to iOS development, so I apologize if I'm missing something obvious or my terminology isn't completely correct. If you need clarification, please let me know in the comments and I'll edit my question accordingly.
The Problem
I'm using Three20, so that might have something to do with it. But I have a "Home view" which is basically a series of images that link out to other views (shown in the image below). If I start our in portrait view, all is well.
The next view is a table view, shown below:
YAY! I can rotate and all is right with the world. BUT if I go back to that home view, rotate to landscape, and THEN go to this tabled view, the world breaks.
You'll see that there's a random space added to the right side of my table now. I don't know where and how it came from. Here's my Controller.m file:
#import "FriendTabsController.h"
#import "MyAppApp.h"
#import "JohnDoeManager.h"
#implementation FriendTabsController
#synthesize innerView, segmentedControl, innerController, friendsController, friendRequestsController;
- (void)addBottomGutter:(UIViewController*)controller {
if ([controller isKindOfClass:[TTTableViewController class]]) {
TTTableViewController* tableViewController = (TTTableViewController*)controller;
tableViewController.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0,0,50+44,0);
tableViewController.tableView.contentInset = UIEdgeInsetsMake(0,0,50+44,0);
}
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Friends";
self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
self.navigationController.navigationBar.tintColor = nil;
friendsController = [[FriendsController alloc] init];
friendRequestsController = [[FriendsController alloc] init];
((FriendsController*)friendRequestsController).friendRequests = YES;
[self addBottomGutter:friendsController];
[self addBottomGutter:friendRequestsController];
innerController = friendsController;
[innerView addSubview:innerController.view];
[innerController viewDidLoad];
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
[self loadBannerAd:(orientation)];
}
-(void) loadBannerAd:(UIInterfaceOrientation)orientation{
MainLayer *mi = [MainLayer getInstance];
if (mi.useJohnDoeAds) {
[[JohnDoeManager sharedInstance] setCurrentViewController:self];
[mi.JohnDoeBanner.view removeFromSuperview];
if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
// This is a portait ad
if ([[MyAppUtils getCurrentDevice] isEqualToString:#"iphone"]) {
[mi.JohnDoeBanner setFrame:CGRectMake(0, 410-44, 320, 50)];
}else{
[mi.JohnDoeBanner setFrame:CGRectMake(0, 1024-44-90-20, 768, 90)];
}
} else {
// Landscape
if ([[MyAppUtils getCurrentDevice] isEqualToString:#"iphone"]) {
[mi.JohnDoeBanner setFrame:CGRectMake(0, 320-44-58, 410, 50)];
}else{
[mi.JohnDoeBanner setFrame:CGRectMake((1024-768)/2, 768-44-90-20, 768, 90)];
}
}
[self.view addSubview:mi.JohnDoeBanner.view];
[mi.JohnDoeBanner rollOver];
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self loadBannerAd:(toInterfaceOrientation)];
}
- (IBAction)didChangeSegment:(UISegmentedControl *)control {
if (innerController) {
[innerController viewWillDisappear:NO];
[innerController.view removeFromSuperview];
[innerController viewDidDisappear:NO];
}
switch (control.selectedSegmentIndex) {
case 0:
innerController = friendsController;
self.title = #"Friends";
break;
case 1:
innerController = friendRequestsController;
self.title = #"Requests";
break;
}
[innerController viewWillAppear:NO];
[innerView addSubview:innerController.view];
[innerController viewDidAppear:NO];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[innerController viewWillAppear:animated];
self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
self.navigationController.navigationBar.tintColor = nil;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[innerController viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[innerController viewWillDisappear:animated];
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated {
[innerController viewDidDisappear:animated];
[super viewDidDisappear:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
[friendsController release], friendsController = nil;
[friendRequestsController release], friendRequestsController = nil;
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
}
#end
So can someone please tell me what's going on? HELP!

You need to set wantsFullScreenLayout property to YES.
in your init methods set
self.wantsFullScreenLayout = YES;
This will solve your problem.

Related

trouble occurred When I pushViewController

Recently, a strange question occurred when I pushViewController to the next viewController.
Why I think it's a strange question? because it don't always appears(The probability of occurrence is low). when it appears, next viewController only shows its nav bar on screen, I still can see the rootViewController, but touching it without reaction(PopGesture is effective).Hoping for your help, thanks very much.
#pragram mark - method of pushing
- (void)clickToAccout {
if (![self countTotalSelectedNumber]) {
[SVProgressHUD showInfoWithStatus:#"没有被选择的商品"];
return;
}
CSCreatOrderViewController *creatOrderVC = [[CSCreatOrderViewController alloc] init];
creatOrderVC.totalPrice = [self countTotalPrice];
creatOrderVC.goods = [self selectedGoods];
[self.navigationController pushViewController:creatOrderVC animated:YES];
}
#pragma mark - chlid class of navgationController
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationBar.tintColor = [UIColor whiteColor];
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return _barStyle;
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
if (self.viewControllers.count > 0) {
viewController.hidesBottomBarWhenPushed = YES;
[SVProgressHUD dismiss];
}
[super pushViewController:viewController animated:animated];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
[SVProgressHUD dismiss];
return [super popViewControllerAnimated:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - tabBarController
- (void)viewDidLoad {
[super viewDidLoad];
CSTabBar *tabBar = [[CSTabBar alloc] init];
[self setValue:tabBar forKey:#"tabBar"];
[self.tabBar setTintColor:[UIColor cz_colorWithHex:0Xec5151]];
[self addChildViewControllerWithTitle:#"首页" imageName:#"home" controllerName:#"CSHomeViewController"];
[self addChildViewControllerWithTitle:#"分类" imageName:#"classify" controllerName:#"CSClassifyViewController"];
[self addChildViewControllerWithTitle:#"查询" imageName:#"search" controllerName:#"CSSearchViewController"];
[self addChildViewControllerWithTitle:#"购物车" imageName:#"cart" controllerName:#"CSShoppingCartViewController"];
[self addChildViewControllerWithTitle:#"我的" imageName:#"mine" controllerName:#"CSMineViewController"];
self.selectedIndex = 0;
}
- (void)addChildViewControllerWithTitle:(NSString *)title imageName:(NSString *)imageName controllerName:(NSString *)controllerName {
Class cls = NSClassFromString(controllerName);
UIViewController *vc = [[cls alloc] init];
vc.title = title;
[vc.tabBarItem setImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#",imageName]]];
[vc.tabBarItem setSelectedImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#_selected",imageName]]];
vc.tabBarItem.title = title;
CSNavigationController *nav = [[CSNavigationController alloc] initWithRootViewController:vc];
[self addChildViewController:nav];
}
#pragma mark - base viewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self setupNavItem];
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
self.navigationController.interactivePopGestureRecognizer.delegate = self;
_indciatorView = [[CSIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
UIWindow *keyW = [UIApplication sharedApplication].keyWindow;
[keyW addSubview:_indciatorView];
[_indciatorView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(keyW);
}];
}
- (void)setupNavItem {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
button.imageEdgeInsets = UIEdgeInsetsMake(9, 0, 9, 29);
[button setImage:[UIImage imageNamed:#"left"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(clickToDismiss) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
}
- (void)clickToDismiss {
[self.navigationController popViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
I think you should change
[super pushViewController:viewController animated:animated];
to
[self.navigationController pushViewController:viewController animated:animated];
And the same when pop
[super popViewControllerAnimated:animated];
to
[self.navigationController popViewControllerAnimated:animated];
I clear the cache of Xcode, this case don't appear. Maybe I Imported a third lib ago caused this case. But like what I asked ,it don't always appears(The probability of occurrence is low). So, hoping it has been well.

iAd is white (not loaded) when application starts

My iAd is white. It looks like bannerViewDidLoadAd is run when the iAd is not fully loaded. It happens only when I show my ViewController first time (application starts). When I go to another controller and return, iAd is loaded properly. Do you have any idea why?
- (void)bannerViewDidLoadAd:(ADBannerView *)banner {
_bannerView.hidden = NO;
[self.view setNeedsLayout];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
_bannerView.hidden = YES;
[self.view setNeedsLayout];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (!_bannerView) {
_bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
_bannerView.delegate = self;
_bannerView.hidden = YES;
CGRect bannerFrame = _bannerView.frame;
bannerFrame.origin.y = self.view.bounds.size.height - _bannerView.bounds.size.height;
_bannerView.frame = bannerFrame;
[self.view addSubview:_bannerView];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
_bannerView.delegate = nil;
[_bannerView removeFromSuperview];
_bannerView = nil;
}

removeFromSuperview ios crashes

My app crashes, not always, at the following method
// overridden
- (void)dismiss
{
[super dismiss];
[containerView_ removeFromSuperview];
containerView_ = nil;
}
crash happens at removerFromSuperview.
There is a "show" method as well
// overridden
- (void)show
{
if (self.parentView == nil)
{
// No parentView, create transparent view as parent
CGSize frameSize = [UIApplication currentSize];
containerView_ = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frameSize.height, frameSize.width)];
containerView_.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
containerView_.backgroundColor = [UIColor clearColor];
self.parentView = containerView_;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
if(some condition )
[[UIApplication sharedApplication].keyWindow.subviews.lastObject addSubview:containerView_];
else
[[UIApplication sharedApplication].keyWindow addSubview:containerView_];
}
else
{
[[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:containerView_];
}
}
[super show];
// This is done to allow the Cancel button to be pressed but nothing else - do after [super show]!
self.superview.userInteractionEnabled = YES;
}
It is strange, that code used to work. I am trying to compile the app for arm64, but I don't understand how that modification impacted those methods.
My app is a non-ARC app, and I cannot go to ARC right now.
Any ideas?
Change your code to dismiss view like this.
// overridden
- (void)dismiss
{
if(containerView_)
[containerView_ removeFromSuperview];
containerView_ = nil;
[super dismiss];
}
Please check with below code -
- (void)dismiss
{
if (containerView_)
{
[containerView_ removeFromSuperview];
containerView_ = nil;
[super dismiss];
}
}
Simply check if container view have superview
- (void)dismiss
{
if ([containerView_ superview])
{
[containerView_ removeFromSuperview];
containerView_ = nil;
[super dismiss];
}
}

Custom alert view in iOS issue

In my app I've to create a custom alert view like the following:
So I followed this tutorial to create a custom alert view. I finished it but I'm getting issue in the following method:
- (void)addOrRemoveButtonWithTag:(int)tag andActionToPerform:(BOOL)shouldRemove {
NSMutableArray *items = [[NSMutableArray alloc]init];
[items addObject:self.buttonOk];
[items addObject:self.buttonClose];
int buttonIndex = (tag == 1);
if (shouldRemove) {
[items removeObjectAtIndex:buttonIndex];
} else {
if (tag == 1) {
[items insertObject:self.buttonOk atIndex:buttonIndex];
} else {
[items insertObject:self.buttonClose atIndex:buttonIndex];
}
}
}
I edited it than the tutorial because I don't need a UIToolBar for buttons. When I run the app it says me that I can't insert a nil object in an NSMutableArray, but I don't understand what's wrong, I hope you can help me to fix this issue.
UPDATE
Here's all the class code I developed:
#import "CustomAlertViewController.h"
#define ANIMATION_DURATION 0.25
#interface CustomAlertViewController ()
- (IBAction)buttonOk:(UIButton *)sender;
- (IBAction)buttonCancel:(UIButton *)sender;
#property (weak, nonatomic) IBOutlet UIButton *buttonClose;
#property (weak, nonatomic) IBOutlet UIButton *buttonOk;
#property (strong, nonatomic) IBOutlet UIView *viewAlert;
-(void)addOrRemoveButtonWithTag:(int)tag andActionToPerform:(BOOL)shouldRemove;
#end
#implementation CustomAlertViewController
- (id)init
{
self = [super init];
if (self) {
[self.viewAlert setFrame:CGRectMake(self.labelAlertView.frame.origin.x,
self.labelAlertView.frame.origin.y,
self.labelAlertView.frame.size.width,
self.viewAlert.frame.size.height)];
[self.buttonOk setTag:1];
[self.buttonClose setTag:0];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)showCustomAlertInView:(UIView *)targetView withMessage:(NSString *)message {
CGFloat statusBarOffset;
if (![[UIApplication sharedApplication] isStatusBarHidden]) {
CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;
if (statusBarSize.width < statusBarSize.height) {
statusBarOffset = statusBarSize.width;
} else {
statusBarOffset = statusBarSize.height;
}
} else {
statusBarOffset = 0.0;
}
CGFloat width, height, offsetX, offsetY;
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft ||
[[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
width = targetView.frame.size.width;
height = targetView.frame.size.height;
offsetX = 0.0;
offsetY = -statusBarOffset;
}
[self.view setFrame:CGRectMake(targetView.frame.origin.x, targetView.frame.origin.y, width, height)];
[self.view setFrame:CGRectOffset(self.view.frame, offsetX, offsetY)];
[targetView addSubview:self.view];
[self.viewAlert setFrame:CGRectMake(0.0, -self.viewAlert.frame.size.height, self.viewAlert.frame.size.width, self.viewAlert.frame.size.height)];
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:ANIMATION_DURATION];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[self.viewAlert setFrame:CGRectMake(0.0, 0.0, self.viewAlert.frame.size.width, self.viewAlert.frame.size.height)];
[UIView commitAnimations];
[self.labelAlertView setText:#"CIAO"];
}
- (void)removeCustomAlertFromView {
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:ANIMATION_DURATION];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[self.viewAlert setFrame:CGRectMake(0.0, -self.viewAlert.frame.size.height, self.viewAlert.frame.size.width, self.viewAlert.frame.size.height)];
[UIView commitAnimations];
[self.view performSelector:#selector(removeFromSuperview) withObject:nil afterDelay:ANIMATION_DURATION];
}
- (void)removeCustomAlertFromViewInstantly {
[self.view removeFromSuperview];
}
- (BOOL)isOkayButtonRemoved {
if (self.buttonOk == nil) {
return YES;
} else {
return NO;
}
}
- (BOOL)isCancelButtonRemoved {
if (self.buttonClose == nil) {
return YES;
} else {
return NO;
}
}
- (void)removeOkayButton:(BOOL)shouldRemove {
if ([self isOkayButtonRemoved] != shouldRemove) {
[self addOrRemoveButtonWithTag:1 andActionToPerform:shouldRemove];
}
}
- (void)removeCancelButton:(BOOL)shouldRemove {
if ([self isCancelButtonRemoved] != shouldRemove) {
[self addOrRemoveButtonWithTag:0 andActionToPerform:shouldRemove];
}
}
- (void)addOrRemoveButtonWithTag:(int)tag andActionToPerform:(BOOL)shouldRemove {
NSMutableArray *items = [[NSMutableArray alloc]init];
[items addObject:self.buttonOk];
[items addObject:self.buttonClose];
int buttonIndex = (tag == 1);
if (shouldRemove) {
[items removeObjectAtIndex:buttonIndex];
} else {
if (tag == 1) {
[items insertObject:self.buttonOk atIndex:buttonIndex];
} else {
[items insertObject:self.buttonClose atIndex:buttonIndex];
}
}
}
- (IBAction)buttonOk:(UIButton *)sender {
[self.delegate customAlertOk];
}
- (IBAction)buttonCancel:(UIButton *)sender {
[self.delegate customAlertCancel];
}
#end
UPDATE 2
Code in which I use the CustomAlertView:
#import "PromotionsViewController.h"
#import "CustomAlertViewController.h"
#interface PromotionsViewController () <CustomAlertViewControllerDelegate> {
BOOL isDeletingItem;
}
#property(nonatomic,strong) CustomAlertViewController *customAlert;
- (IBAction)buttonBack:(UIButton *)sender;
#property (weak, nonatomic) IBOutlet UIButton *buttonAlert;
- (IBAction)buttonAlert:(UIButton *)sender;
#end
#implementation PromotionsViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.buttonAlert setTitle:self.promotionSelected forState:UIControlStateNormal];
[self.customAlert setDelegate:self];
isDeletingItem = NO;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonBack:(UIButton *)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)buttonAlert:(UIButton *)sender {
self.customAlert = [[CustomAlertViewController alloc]init];
[self.customAlert removeOkayButton:NO];
[self.customAlert removeCancelButton:NO];
NSString *message = [NSString stringWithFormat:#"La tua offerta %# del 20%% è stata convertita in punti IoSi x10", self.promotionSelected];
[self.customAlert showCustomAlertInView:self.view withMessage:message];
isDeletingItem = YES;
}
- (void)customAlertOk {
if (isDeletingItem) {
[self.customAlert removeCustomAlertFromViewInstantly];
} else {
[self.customAlert removeCustomAlertFromView];
}
}
- (void)customAlertCancel {
[self.customAlert removeCustomAlertFromView];
if (isDeletingItem) {
isDeletingItem = NO;
}
}
#end
Maybe you're calling addOrRemoveButtonWithTag:andActionToPerform: at a time where your UI is not fully created, since UI elements are created asynchronously. So if you call this method, right after custom alert view instanciation, you'll get your crash because the buttons in the view are not created.
To solve this issue, you need to call addOrRemoveButtonWithTag:andActionToPerform: only once your custom alert has been added to the view hierarchy.
EDIT :
With the example code you gave in edit 2, you call these lines :
- (IBAction)buttonAlert:(UIButton *)sender {
self.customAlert = [[CustomAlertViewController alloc]init];
[self.customAlert removeOkayButton:NO];
[self.customAlert removeCancelButton:NO];
}
but when you have just instantiated CustomAlertViewController, its 2 buttons are not yet created, so I suggest you add 2 properties hasOkButton and hasCancelButton and a new constructor to your custom class like this one :
- (instancetype) initWithOk:(BOOL)OkButton AndCancel:(BOOL) CancelButton
{
if(self = [super init])
{
hasOkButton = OkButton;
hasCancelButton = CancelButton;
}
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// At this time, the custom UI buttons will be created in the UI view hierarchy
[self removeOkayButton: hasOkButton];
[self removeOkayButton: hasCancelButton];
}
And in the caller you can use the following to display a custom alert View:
- (IBAction)buttonAlert:(UIButton *)sender {
self.customAlert = [[CustomAlertViewController alloc] initWithOk:NO AndCancel:NO];
// ...
}
EDIT #2
I tried your solution in a real project, I made it work by using these lines int the caller :
- (IBAction)buttonAlert:(UIButton *)sender {
self.customAlert = [self.storyboard instantiateViewControllerWithIdentifier:#"customAlertView"];
self.customAlert.hasOK = NO;
self.customAlert.hasCancel = YES;
NSString *message = [NSString stringWithFormat:#"La tua offerta %# del 20%% è stata convertita in punti IoSi x10", self.promotionSelected];
[self.customAlert showCustomAlertInView:self.view withMessage:message];
isDeletingItem = YES;
}
In the CustomAlertViewController declare 2 visible properties hasOK and hasCancel in.h.
And modify your .m by adding method :
-(void)viewWillAppear:(BOOL)animated
{
[self removeOkayButton:self.hasOK];
[self removeCancelButton:self.hasCancel];
}
Be sure to modify your storyboard (if eligible) to have the "customAlertView" defined this way :
Don't forget also to bind your UIButton to the controller this can be a mistake too in your implementation :
Hope this will help you :)
I found on the web a tutorial to create custom alert view by using code, if you are interested you can go to this tutorial. I used it for my issue and it worked great! You have to fix a few things, because it uses deprecated command but it's easy to fix it.
If you are interested just take a look about this tutorial. I think you can integrate it in your app and after you can easily use for other stuff if it's necessary. I hope that my answer will help someone.

Sliding Between UISegmentedControl Views

Currently I am wanting to create a slide animation when the user selects on a segmented button of a UISegmentedControl instantiated on top of a navigationbar. Currently I have a UISegmentedControl with 6 buttons the user is allowed to press and select to go to different views.
Everything works accordingly but I am having an issue with implementing the slide transition, if it is even possible.
I am able to implement a slide transition between UITabBar views using this method:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
int controllerIndex = [[tabBarController viewControllers] indexOfObject:viewController];
if(controllerIndex == self.selectedIndex || self.isAnimating){
return NO;
}
// Get the views.
UIView * fromView = tabBarController.selectedViewController.view;
UIView * toView = [viewController view];
// Get the size of the view area.
CGRect viewSize = fromView.frame;
BOOL scrollRight = controllerIndex > tabBarController.selectedIndex;
// Add the to view to the tab bar view.
[fromView.superview addSubview:toView];
// Position it off screen.
toView.frame = CGRectMake((scrollRight ? 320 : -320), viewSize.origin.y, 320, viewSize.size.height);
[UIView animateWithDuration:0.2 animations: ^{
// Animate the views on and off the screen. This will appear to slide.
fromView.frame =CGRectMake((scrollRight ? -320 : 320), viewSize.origin.y, 320, viewSize.size.height);
toView.frame =CGRectMake(0, viewSize.origin.y, 320, viewSize.size.height);
} completion:^(BOOL finished) {
if (finished) {
// Remove the old view from the tabbar view.
[fromView removeFromSuperview];
tabBarController.selectedIndex = controllerIndex;
}
}
];
return NO;
}
Not so sure if the same rules apply for a UISegmentedControl of several viewcontrollers. Is this possible to do? I figure it should be but anyone have any ideas on how to get started?
EDIT
Heres the code I use within my segmentedcontroller...
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
/* This bunch of code creates the segmentedControllerButtons in the nav bar */
self.segmentedViewControllers = [self segmentedViewControllerContent];
NSArray * segmentTitles = #[#"Plant", #"Net", #"Wiz", #"Date", #"Clone", #"GF/E"];
self.segmentedControl = [[UISegmentedControl alloc]initWithItems:segmentTitles];
self.segmentedControl.selectedSegmentIndex = 0;
self.segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
[self.segmentedControl addTarget:self action:#selector(didChangeSegmentControl:) forControlEvents:UIControlEventValueChanged];
self.navigationItem.titleView = self.segmentedControl;
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
self.segmentedControl.tintColor = [UIColor redColor];
[self didChangeSegmentControl:self.segmentedControl]; // kick everything off
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSArray *)segmentedViewControllerContent {
CDDConfigPlantViewController *plant = [[CDDConfigPlantViewController alloc] initWithNibName:#"CDDConfigPlantViewController" bundle:nil];
plant->ipAddress = ipAddress;
plant->encode = encodedInfo;
CDDConfigNetworkViewController *network = [[CDDConfigNetworkViewController alloc] initWithNibName:#"CDDConfigNetworkViewController" bundle:nil];
network->ipAddress = ipAddress;
network->encode = encodedInfo;
CDDConfigAcquisitionWizardViewController *acquisition_wizard = [[CDDConfigAcquisitionWizardViewController alloc] initWithNibName:#"CDDConfigAcquisitionWizardViewController" bundle:nil];
acquisition_wizard->ipAddress = ipAddress;
acquisition_wizard->encode = encodedInfo;
CDDConfigDateTimeViewController *date_time = [[CDDConfigDateTimeViewController alloc] initWithNibName:#"CDDConfigDateTimeViewController" bundle:nil];
date_time->ipAddress = ipAddress;
date_time->encode = encodedInfo;
CDDConfigCDDCloneViewController *cdd_clone = [[CDDConfigCDDCloneViewController alloc] initWithNibName:#"CDDConfigCDDCloneViewController" bundle:nil];
cdd_clone->ipAddress = ipAddress;
cdd_clone->encode = encodedInfo;
CDDConfigGroundfaultEnergyViewController *groundfault_energy = [[CDDConfigGroundfaultEnergyViewController alloc] initWithNibName:#"CDDConfigGroundfaultEnergyViewController" bundle:nil];
groundfault_energy->ipAddress = ipAddress;
groundfault_energy->encode = encodedInfo;
NSArray * controllers = [NSArray arrayWithObjects:plant, network, acquisition_wizard, date_time, cdd_clone, groundfault_energy, nil];
return controllers;
}
#pragma mark -
#pragma mark Segment control
- (void)didChangeSegmentControl:(UISegmentedControl *)control {
if (self.activeViewController) {
[self.activeViewController viewWillDisappear:NO];
[self.activeViewController.view removeFromSuperview];
[self.activeViewController viewDidDisappear:NO];
}
self.activeViewController = [self.segmentedViewControllers objectAtIndex:control.selectedSegmentIndex];
[self.activeViewController viewWillAppear:YES];
[self.view addSubview:self.activeViewController.view];
[self.activeViewController viewDidAppear:YES];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.activeViewController viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.activeViewController viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.activeViewController viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.activeViewController viewDidDisappear:animated];
}
Is it UIView you want to animate or UIViewControllers.
If UIView the animateWithDuration: animations: completion: works
if UIViewControllers presentViewController: animated: completion: is the way to go

Resources