Reload viewcontroller - reload

How can I refresh a viewcontroller?.
I.e. I have a series of animations that run into the viewdidload and want to reload the viewcontroller again, really it would be reload the viewdidload again?
It would be an action assigned to a UIButton
thanks

You should do it by that way:
- (void)viewDidLoad {
[self setUpInterface];
}
//for UIButton Action
- (IBAction)buttonTapped: (id)sender {
[self setUpInterface];
}
//for your aninmations
- (void)setUpInterface {
//your code for animation here
}
don't try to call viewDidLoad, it isn't good. Goodluck!

Related

iOS: Pointer get lost when poping back to parentView

I code for iOS 6.1 with ARC and have a problem that my objects in the nsmutablearray get "lost".
I will explain it in more detail:
There is a parent view which has a NSMutableArray which should hold some objects(addresses)
Everytime I hit the button the data of the Array will be displayed with NSLog and then the navigation controller pushes to the ChildView
The childview generates a new address object
If I do this and then press the back button in the view and wants to try the same case (again pressing the button) the data in the array is lost and I get a EXC_BAD_ACCESS
My assumption: When I go back to parentView ARC deallocates the second view and everything in it. But my Address object will be referenced from the array so that the ARC counter for this object should not be 0.
Can anyone help me?
Here is the concrete code
ParentViews Controller h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (nonatomic, strong) NSMutableArray *adresses;
#property int count;
-(void)goFurther;
#end
ParentViews Controller m:
#import "ViewController.h"
#import "SecondViewController.h"
#import "Address.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
self.title=#"First View";
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithTitle:#"Add address" style:UIBarButtonItemStylePlain
target:self action:#selector(goFurther)];
[self.navigationItem setLeftBarButtonItem:addButton];
self.adresses=[[NSMutableArray alloc] init];
self.count=0;
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) goFurther{
for (Address *a in self.adresses) {
NSLog(#"Adresse:");
NSLog(a.street);
NSLog(a.door);
}
self.count++;
SecondViewController *second=[[SecondViewController alloc]initWithView:self];
[self.navigationController pushViewController:second animated:true];
}
#end
ChildViews Controller h:
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface SecondViewController : UIViewController
#property ViewController * viewCon;
-(id) initWithView: (ViewController*) view;
#end
ChildViews Controller m:
#import "SecondViewController.h"
#import "Address.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(id) initWithView: (ViewController*) view{
self = [super init];
self.viewCon=view;
Address *a=[Address alloc];
a.street=[NSString stringWithFormat:#"Street %d", self.viewCon.count];
a.door=#"Door";
[self.viewCon.adresses addObject: a];
return self;
}
- (void)viewDidLoad
{
self.title=#"Second View";
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
You have to send your data back to the parent view before dismissing the child view.
Declare a #protocol (say, called ChildControllerDelegate) in your child controller's .h file with a method didDismissWithData: with some data type that is suitable for you (maybe string or dictionary). Have the parent view controller conform to the protocol. Create a #property of the child called delegate of type id<ChildControllerDelegate>
Then before dismissing the child, call
[self.delegate didDismissWithData:newData];
In the parent controller, handle this message and save your new address.

ios 6.0 - Landscape not working - subclassed UINavigationController never calls shouldAutorotate method

I have created a simple application which has a red background and a button on it (for the purposes of understanding this problem). The app is in landscape mode and being built with iOS6 framework.
I have set the Supported interface orientations pList properties to only have: Landscape (right home button)
If I put the methods -(BOOL)shouldAutorotate and -(NSUInteger)supportedInterfaceOrientations in the view controller and initiate it as the windows rootViewController WITHOUT using a UINavigationController then landscape orientation is achieved.
HOWEVER if I use a subclassed UINavigationController like in the example below and implement -(BOOL)shouldAutorotate and -(NSUInteger)supportedInterfaceOrientations , landscape orientation is NOT achieved and -(BOOL)shouldAutorotate is never called.
I have the following code in my Subclassed UINavigationController:
//For iOS 5.x and below
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationLandscapeRight);
}
//For iOS 6.0
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight;
}
-(BOOL)shouldAutorotate
{
return YES;
}
In my appDelegate I have these methods:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
viewController = [[MDViewController alloc] init]; //a very simple viewcontroller containing button on red background which should be in landscape mode
navigationController = [[MDNavigationController alloc] initWithRootViewController:viewController];
[self.window setRootViewController:navigationController.topViewController];
[self.window makeKeyAndVisible];
return YES;
}
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow: (UIWindow *)window {
return UIInterfaceOrientationMaskLandscapeRight;
}
I have seen countless answers to similar questions which I implemented but found that they fail to work.
Thanks.
Shouldn't you be doing this:
[self.window setRootViewController:navigationController];
instead of:
[self.window setRootViewController:navigationController.topViewController];

iOS 6 UITabBarController supported orientation with current UINavigation controller

I have an iPhone app I am updating to iOS 6 that is having rotation issues. I have a UITabBarController with 16 UINavigationCotrollers. Most of the subviews can work in portrait or landscape but some of them are portrait only. With iOS 6 things are rotating when they shouldn't.
I tried subclassing the tabBarController to return the supportedInterfaceOrienations of the current navigationController's selected viewController:
- (NSUInteger)supportedInterfaceOrientations{
UINavigationController *navController = (UINavigationController *)self.selectedViewController;
return [navController.visibleViewController supportedInterfaceOrientations];
}
This got me closer. The view controller won't rotate out of position when visible, but if I am in landscape and switch tabs the new tab will be in landscape even if it isn't supported.
Ideally the app will only be in the supported orienation of the current visible view controller. Any ideas?
Subclass your UITabBarController overriding these methods:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// You do not need this method if you are not supporting earlier iOS Versions
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
Subclass your UINavigationController overriding these methods:
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
Then implement these methods in your viewControllers that you do not want to rotate:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
And for viewControllers that you do want to rotate:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
-(BOOL)shouldAutorotate
{
return YES;
}
Your tabbarController should be added as the RootviewController of the app window. If you plan to support the default orientations, all but upsidedown is default for iPhone, then you do not need to do anything else. If you want to support upside-down or if you do not want to support another of the orientations, then you need to set the appropriate values in app delegate and/or info.plist.
I had issue that some View controllers in the navigation stack support all the orientations, some only portrait, but UINavigationController was returning all app supported orientations, this little hack helped me. I'm not sure if this is intended behavior or what
#implementation UINavigationController (iOS6OrientationFix)
-(NSUInteger) supportedInterfaceOrientations {
return [self.topViewController supportedInterfaceOrientations];
}
#end
I think is better something like that (as a category method)
-(NSUInteger) supportedInterfaceOrientations {
if([self.topViewController respondsToSelector:#selector(supportedInterfaceOrientations)])
{
return [self.topViewController supportedInterfaceOrientations];
}
return UIInterfaceOrientationMaskPortrait;
}
this ensures that the method is implemented. If you aren't doing this check and the method is not implemented (like in iOS5 env) the app should crash!
If you plan to enable or disable rotation for all view controllers you don't need to subclass UINavigationController.
Instead use:
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
in your AppDelegate.
If you plan to support all orientations in your app but different orientations on PARENT View Controllers (UINavigationController stack for example) you should use
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
from AppDelegate in combination with the following methods in your PARENT View Controller.
- (BOOL)shouldAutorotate
and
- (NSUInteger)supportedInterfaceOrientations
But if you plan to have different orientation settings in different CHILDREN ViewControllers in the same navigation stack (like me) you need to check the current ViewController in the navigation stack.
I've created the following in my UINavigationController subclass:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
int interfaceOrientation = 0;
if (self.viewControllers.count > 0)
{
DLog(#"%#", self.viewControllers);
for (id viewController in self.viewControllers)
{
if ([viewController isKindOfClass:([InitialUseViewController class])])
{
interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
else if ([viewController isKindOfClass:([MainViewController class])])
{
interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
else
{
interfaceOrientation = UIInterfaceOrientationMaskAllButUpsideDown;
}
}
}
return interfaceOrientation;
}
Since you cannot control anymore from children ViewControllers the rotation settings of presented view controller you must somehow intercept what view controller is currently in the navigation stack. So that's what I did :). Hope that helps !

How to log the backbutton that comes with the navigationcontroller

I am creating a new view using
[[self navigationController]pushViewController:newViewController animated:YES];
The new view (newViewController) stacks on the top of the previous, and comes with a backbutton. I need to access this backbutton to override it. To begin with, finding out how to NSLog a string when the back button is pushed will be of great help.
Best, Tom
I found the answer myself.
I have to make a new backbutton in the viewDidLoad function, and add a selector.
-(void) viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"myTitle"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(mySelector:)];
self.navigationItem.leftBarButtonItem = backButton;
}
Then the selector:
-(void)mySelector
{
NSLog(#"backButton pushed");
}

Cannot make UIPopover appear programmatically

I want the pop-over to appear when the app is first launched in portrait mode instead of it being hidden and requiring the user to hit the button before the popover appears. I've tried to find solutions through the likes of Google and other StackOverflow threads, but I have not been able to figure it out. So in the event the standard SplitView sample that is created by XCode is different I'll put the code below. If I can make it work on this app I'm hoping that I can understand it and be able to apply it elsewhere.
I thought about trying to just call what is called when the button is pushed... but I can't figure out what is called and where it is declared... I feel like I'm overlooking something basic and it's driving me bananas!
The DetailView Controller
DetailViewController.h
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController <UIPopoverControllerDelegate, UISplitViewControllerDelegate> {
UIPopoverController *popoverController;
UIToolbar *toolbar;
id detailItem;
UILabel *detailDescriptionLabel;
}
#property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
#property (nonatomic, retain) id detailItem;
#property (nonatomic, retain) IBOutlet UILabel *detailDescriptionLabel;
#end
DetailViewController.m
#import "DetailViewController.h"
#import "RootViewController.h"
#interface DetailViewController ()
#property (nonatomic, retain) UIPopoverController *popoverController;
- (void)configureView;
#end
#implementation DetailViewController
#synthesize toolbar, popoverController, detailItem, detailDescriptionLabel;
#pragma mark -
#pragma mark Managing the detail item
/*
When setting the detail item, update the view and dismiss the popover controller if it's showing.
*/
- (void)setDetailItem:(id)newDetailItem {
if (detailItem != newDetailItem) {
[detailItem release];
detailItem = [newDetailItem retain];
// Update the view.
[self configureView];
}
if (self.popoverController != nil) {
[self.popoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView {
// Update the user interface for the detail item.
detailDescriptionLabel.text = [detailItem description];
}
#pragma mark -
#pragma mark Split view support
- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc {
barButtonItem.title = #"Root List";
NSMutableArray *items = [[toolbar items] mutableCopy];
[items insertObject:barButtonItem atIndex:0];
[toolbar setItems:items animated:YES];
[items release];
self.popoverController = pc;
}
// Called when the view is shown again in the split view, invalidating the button and popover controller.
- (void)splitViewController: (UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
NSMutableArray *items = [[toolbar items] mutableCopy];
[items removeObjectAtIndex:0];
[toolbar setItems:items animated:YES];
[items release];
self.popoverController = nil;
}
#pragma mark -
#pragma mark Rotation support
// Ensure that the view controller supports rotation and that the split view can therefore show in both portrait and landscape.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
#pragma mark -
#pragma mark View lifecycle
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
/*
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
*/
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.popoverController = nil;
}
#pragma mark -
#pragma mark Memory management
/*
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
*/
- (void)dealloc {
[popoverController release];
[toolbar release];
[detailItem release];
[detailDescriptionLabel release];
[super dealloc];
}
#end
The rootview is a typical UITableViewController and is nothing special, but if for some reason you need that or the delegate (which is pretty boring minus loading the views) to help me figure out this problem I have no problems posting those also. Again this is straight up what XCode generates when I tell it I want to create a split view for the iPad and I have not modified it.
Hopefully there is something very minor I'm overlooking and it will make me smack my head and say "I can't believe I missed that!" Thanks for your help.
Figured it out!
I put
[self.popoverController presentPopoverFromBarButtonItem:[[toolbar items] objectAtIndex:0] permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
in the ViewDidLoad method. I knew it was something pretty simple! It seems to work without any problems!

Resources