i have master view controller which consists of several buttons instead of tableview. I want to open a different detail views upon different button clicks.
I have code listed below, but this does not show any changes.
- (IBAction)NewEntryBtn:(UIButton *)sender
{
NSLog(#"new entry btn");
[self.appdelegate.splitViewController viewWillDisappear:YES];
NSMutableArray *viewControllerArray=[[NSMutableArray alloc] initWithArray:[[self.appdelegate.splitViewController.viewControllers objectAtIndex:1]viewControllers]];
[viewControllerArray removeLastObject];
self.secondVC=[[SecondDetailViewController alloc] init];
[viewControllerArray addObject:self.secondVC];
self.appdelegate.splitViewController.delegate = self.secondVC;
[[self.appdelegate.splitViewController.viewControllers objectAtIndex:1] setViewControllers:viewControllerArray animated:NO];
[self.appdelegate.splitViewController viewWillAppear:YES];
}
- (IBAction)EditBtn:(UIButton *)sender
{
[self.appdelegate.splitViewController viewWillDisappear:YES];
NSMutableArray *viewControllerArray=[[NSMutableArray alloc] initWithArray:[[self.appdelegate.splitViewController.viewControllers objectAtIndex:1]viewControllers]];
[viewControllerArray removeLastObject];
self.secondVC=[[SecondDetailViewController alloc] init];
[viewControllerArray addObject:self.secondVC];
self.appdelegate.splitViewController.delegate = self.secondVC;
[[self.appdelegate.splitViewController.viewControllers objectAtIndex:1] setViewControllers:viewControllerArray animated:NO];
[self.appdelegate.splitViewController viewWillAppear:YES];
}
could anyone suggest changes?
Well, you can do this by only one method. First set tag to all the buttons and add reference of all the buttons to single method.
- (IBAction)btnClicked:(id)sender
{
int btnNo = ((UIControl *) sender).tag;
NSLog(#"Button Clicked - %d", btnNo);
if (btnNo == 1)
{
// Navigate to first detail view controller
}
else if (btnNo == 2)
{
// Navigate to second detail view controller
}
.
.
and so on.
}
Related
i have asked this question here also but i didn't get any solution.so i am asking here again with the full explanation.
I downloaded EPub Reader library from here. When i run this library,first comes a table view which contain four rows having values EPUB ,PDF etc and after clicking on the "EPUB" row
book appears successfully with the top toolbar. Because i have to load the book first in start instead of showing the toolbar i did some changes with the code. copied some code from didSelectRowAtIndexPath and added that code into delegate.m. so now the problem is book is successfully loading but the toolbar is not showing up
here is my code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSArray *languages = [userDefaults objectForKey:#"AppleLanguages"];
EPubViewController *epubView = [[EPubViewController alloc] init];
[epubView loadEpub:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"AtoZbook" ofType:#"epub"]]];
self.navigationController = [[UINavigationController alloc]initWithRootViewController:epubView];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
the code of loading epubView was in RootViewController.m in the original library
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.row) {
//TXT
case 0:{
//txt
}
break;
//PDF
case 1:{
//PDF
}
break;
//EPUB
case 2:{
epubView = [[EPubViewController alloc] init];
[epubView loadEpub:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"The Chessmen of Mars" ofType:#"epub"]]];
epubView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:epubView animated:YES];
[epubView release];
}
break;
case 3:{
//another book
}
break;
default:
break;
}
}
here is my view didLoadMethod of EpubViewController
- (void)viewDidLoad {
[super viewDidLoad];
loadingIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
loadingIndicator.center = CGPointMake(toolbar.frame.size.width/2 ,toolbar.frame.size.height/2);
[loadingIndicator startAnimating];
toolbar.alpha = 0.8;
[self.toolbar addSubview:loadingIndicator];
[webView setDelegate:self];
UIScrollView* sv = nil;
for (UIView* v in webView.subviews) {
if([v isKindOfClass:[UIScrollView class]]){
sv = (UIScrollView*) v;
sv.scrollEnabled = NO;
sv.bounces = NO;
}
}
currentTextSize = 100;
//Webview
UISwipeGestureRecognizer* rightSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(gotoNextPage)] ;
[rightSwipeRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft];
UISwipeGestureRecognizer* leftSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(gotoPrevPage)] ;
[leftSwipeRecognizer setDirection:UISwipeGestureRecognizerDirectionRight];
[webView addGestureRecognizer:rightSwipeRecognizer];
[webView addGestureRecognizer:leftSwipeRecognizer];
[self performSelector:#selector(stratRolling)];
}
here are the images
i want to say again that the toolbar works fine when i show the epubViewController from the Case 2 i mean by clicking the row if i have to show the table view first.
your tool bar is hiding being navigation bar since navigation bar is always on top you can add your tool bar as sub view of navigation bar i m not sure if it will work though best approch is use navigation bar and add item it it like left button right button and title stuff or you can add a view as subview of navigation bar i have done that before sample code
navBar=self.navigationController.navigationBar;
[navBar addSubview:statusBar];
statusBar.frame=f;
self.navigationController.navigationBar.translucent = YES;
here statusBar was a view was set up like your tool bar same size.
I've got a standard UINavigation controller and push my screens with push and pop as normal. However, i have one screen that switches between two view controllers on a button press so the screen flips over top reveal the other viewcontroller and visa versa. You can switch between them at will.
Now, I want the back button to work as normal so I swap the top view controller to achieve this as follows:
-(IBAction)switchToSlowProductEntry:(id)sender
{
NSLog(#"Switching to slow product entry");
// Replace the top view with the findProductView
FindProductView *findProdView = [ProductViewInstances shared].findProductView;
NSMutableArray *views = [self.navigationController.viewControllers mutableCopy];
[views removeLastObject];
[views addObject:findProdView];
// if sender is nil then assume we started from the viewDidLoad so no animation
if(sender)
{
[UIView transitionWithView:self.navigationController.view duration:0.3 options:UIViewAnimationOptionTransitionFlipFromRight animations:^
{
[self.navigationController setViewControllers:views animated:NO];
}
completion:^(BOOL finished) {}];
}
else
[self.navigationController setViewControllers:views animated:NO];
NSLog(#"Views: %#", views);
[views release];
[ProductViewInstances shared].lastScreen = SlowProductEntryView;
}
-(IBAction)switchToQuickProductEntry:(id)sender
{
NSLog(#"Switching to fast product entry");
// Replace the top view with the findProductView
QuickOrderEntryView *quickProductView = [ProductViewInstances shared].quickProductView;
NSMutableArray *views = [self.navigationController.viewControllers mutableCopy];
[views removeLastObject];
[views addObject:quickProductView];
if(sender)
{
[UIView transitionWithView:self.navigationController.view duration:0.3 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^
{
[self.navigationController setViewControllers:views animated:NO];
}
completion:^(BOOL finished) {}];
}
else
[self.navigationController setViewControllers:views animated:NO];
NSLog(#"Views: %#", views);
[views release];
[ProductViewInstances shared].lastScreen = QuickProductEntryView;
}
I have a similar piece of code for the other screen. I'm using the ProductViewInstances class to maintain the two view controllers as I do not want the classes to get unloaded as I'm maintaining stage on the screen.
When you want to move forward from these screens, I do the push as normal to a new screen. It work and I go back after reviewing the products I added. If I press back I get back to the above screen and everything seems normal. However, when I press my custom back button (I need to do processing if back pressed) I run into a problem.
The popViewController does nothing. Here is the code in the base class to manage the custom back button.
-(void) viewDidLoad
{
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Back", nil)
style:UIBarButtonItemStyleBordered
target:self
action:#selector(myCustomBack)] autorelease];
if(![ProductViewInstances shared].findProductView)
{
[ProductViewInstances shared].findProductView = [[FindProductView alloc] init];
[ProductViewInstances shared].findProductView.customer = self.customer;
}
if(![ProductViewInstances shared].quickProductView)
{
[ProductViewInstances shared].quickProductView = [[QuickOrderEntryView alloc] init];
[ProductViewInstances shared].quickProductView.customer = self.customer;
}
}
-(void) goBack
{
if([[ProductViewInstances shared].quickProductView checkIfItemsPending])
{
// Pop up dialog
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Save Entries", nil)
message:NSLocalizedString(#"Your entries will be lost", nil)
delegate:self
cancelButtonTitle:NSLocalizedString(#"Cancel", nil)
otherButtonTitles:NSLocalizedString(#"Save", nil), nil];
[alert show];
[alert release];
}
else
{
// Remove rows from quick item entry screen
[[ProductViewInstances shared].quickProductView removeRowsFromtable];
if(didPressHome)
[self popToSpringBoard:YES];
else
[self.navigationController popViewControllerAnimated:YES];
}
}
So when I press back I have to check if the entries will be lost. The pop to SpringBoard pops back a couple of screens and basically calls the following:
NSArray *controllers = appDelegate.navigationController.viewControllers;
UIViewController *springboard = [controllers objectAtIndex:2];
[appDelegate.navigationController popToViewController:springboard animated:animated];
However, the popViewController animated call does nothing... Like as if it never happened.
Donie
#selector(myCustomBack) will not call goBack unless you left out some code.
In my tableview containing 8 row datas, I want to show the 8 label and 8 textfield in otherview, for ex: If the user selects(checkmarked) 4 rows in uitableview means I want to show 4 label and 4 texfield in other view. Can any one help me for this logic?
- (void)viewDidLoad
{
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]];
[lb5 setHidden:YES];
[text5 setHidden:YES];
[lb6 setHidden:YES];
[text6 setHidden:YES];
//[lb7 setHidden:YES];
//[text7 setHidden:YES];
//[lb8 setHidden:YES];
//[text8 setHidden:YES];
scrollView.frame = CGRectMake(0, 0, 320, 460);
[scrollView setContentSize:CGSizeMake(320, 678)];
int s=[am.genar count];
am=(AppDelegate*)[[UIApplication sharedApplication] delegate];
NSLog(#"test %d",[am.genar count]);
NSLog(#"test %#",[am.genar objectAtIndex:0]);
lb1.text=[am.genar objectAtIndex:0];
NSLog(#"test %#",[am.genar objectAtIndex:1]);
lb2.text=[am.genar objectAtIndex:1];
NSLog(#"test %#",[am.genar objectAtIndex:2]);
lb3.text=[am.genar objectAtIndex:2];
NSLog(#"test %#",[am.genar objectAtIndex:3]);
lb4.text=[am.genar objectAtIndex:3];
if(s>3)
{
[lb5 setHidden:NO];
[text5 setHidden:NO];
[lb6 setHidden:NO];
[text6 setHidden:NO];
// [lb7 setHidden:NO];
// [text7 setHidden:NO];
// [lb8 setHidden:NO];
// [text8 setHidden:NO];;
NSLog(#"test %#",[am.genar objectAtIndex:4]);
lb5.text=[am.genar objectAtIndex:4];
NSLog(#"test %#",[am.genar objectAtIndex:5]);
lb6.text=[am.genar objectAtIndex:5];
// NSLog(#"test %#",[am.genar objectAtIndex:6]);
// lb7.text=[am.genar objectAtIndex:6];
// NSLog(#"test %#",[am.genar objectAtIndex:7]);
// lb8.text=[am.genar objectAtIndex:7];
}
[super viewDidLoad];
}
right now I'm using this logic for showing texfield and label, but it showing error if user selects 5 rows and it's working 6 rows. can any help me to clear?
Following your application design it might have sense to use the table view in the second view controller, it will be easy to create as many rows as needed and display the titles correctly.
If you need to use the outlet labels and textfields, i'd make it like
NSArray * arrayOfLabelsAndTextViews = [NSArray arrayWithObjects:lb1, text1, lb2, text2, lb3, text3, lb4, text4, lb5, text5, lx6, text6, lb7, text7, lb8, text8, nil];
With the help of this array you can quickly enumerate through all the label/text pairs accessing it as:
i - pair index
i*2 - label index
i*2 +1 - text index
Then you need to show exactly the number of pairs checked at the previos view:
am=(AppDelegate*)[[UIApplication sharedApplication] delegate];
const int totalPairsCount = 8;
for(int i = 0; i<totalPairsCount; i++) {
UILabel * pairLabel = [arrayOfLabelsAndTextViews objectAtIndex:i*2];
UITextView * pairText = [arrayOfLabelsAndTextViews objectAtIndex:i*2 +1];
BOOL isPairVisible = i < am.count;
if (isPairVisible) {
pairLabel.text = [am objectAtIndex:i];
pairText.text = #"";
}
pairLabel.hidden = !isPairVisible;
pairText.hidden = !isPairVisible;
}
I don't think that is production quality code but at list it must help you understand how do you operate the data and use the UI elements.
dont code like this..,
int s=[am.genar count];
am=(AppDelegate*)[[UIApplication sharedApplication] delegate];
add S values after declaration of AppDelegate Variable.,
am=(AppDelegate*)[[UIApplication sharedApplication] delegate];
int s=[am.genar count];
and try to print the values.,.
On Click of Check Mark add that particular string to an Global Array. From that you can get an Global array count
In Second View
View Did Load Method
create a for loop
(int i =0 ; i < appDelegate.globalArray; i++)
{
Here you can create a label Dynamically whatever number will be. your labels will create according to that
}
if you have any questions feel free to ask
I've made a test app to familiarize myself with making a custom container view controller. If I rotate the device when the app first starts or after switching to a different view controller, the new view resizes to take up the whole screen, as I intended. However, if I rotate after the app starts, and then switch to a new view controller, the view keeps its portrait size instead of getting shorter and wider (actually it's slightly different -- it goes from 320,460 to 300,480). The master view controller is alloc init'd in the app delegate (no xib) and set as the window's root view controller. Here is the code I have in my MasterViewController (the custom container controller):
- (void)viewDidLoad {
[super viewDidLoad];
WelcomeController *welcome = [[WelcomeController alloc] initWithNibName:#"ViewController" bundle:nil];
self.currentController = welcome;
[self addChildViewController:welcome];
[self.view addSubview:welcome.view];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeft:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeLeft];
}
- (void)swipeLeft:(UISwipeGestureRecognizer *)gesture {
if (gesture.state == UIGestureRecognizerStateRecognized) {
UIActionSheet *sheet =[[UIActionSheet alloc] initWithTitle:#"Select A Destination" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"welcome",#"Play",#"Scores", nil];
[sheet showInView:self.view];
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0:{
if ([self.currentController class] != [WelcomeController class] ) {
WelcomeController *welcome = [[WelcomeController alloc] initWithNibName:#"ViewController" bundle:nil];
[self addChildViewController:welcome];
[self moveToNewController:welcome];
}
break;
}
case 1:{
if ([self.currentController class] != [PlayViewController class] ) {
PlayViewController *player = [[PlayViewController alloc] initWithNibName:#"PlayViewController" bundle:nil];
[self addChildViewController:player];
[self moveToNewController:player];
}
break;
}
case 2:{
if ([self.currentController class] != [HighScores class] ) {
HighScores *scorer = [[HighScores alloc] initWithNibName:#"HighScores" bundle:nil];
[self addChildViewController:scorer];
[self moveToNewController:scorer];
}
break;
}
case 3:
NSLog(#"Cancelled");
break;
default:
break;
}
}
-(void)moveToNewController:(id) newController {
[self.currentController willMoveToParentViewController:nil];
[self transitionFromViewController:self.currentController toViewController:newController duration:.6 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{}
completion:^(BOOL finished) {
[self.currentController removeFromParentViewController];
[newController didMoveToParentViewController:self];
self.currentController = newController;
}];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;//(interfaceOrientation == (UIInterfaceOrientationPortrait | UIInterfaceOrientationLandscapeLeft));
}
Any ideas why this is happening (I don't know if this means that the master view controller's view isn't resizing, but when I get this non-resizing behavior the gesture recognizer only responds in the narrow view, not over the whole screen)?
You are not sending rotation messages to your child view controllers. At least not in the code you posted. After switching Child Controller you are even removing previous child from ChildViewControllers array with [self.currentController removeFromParentViewController] so even if you implement - (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers you have always only one ChildViewController in your ParentViewController.
I have got this working, so i will paste you how am i doing this. First i create all my ViewControllers, add them as child view controllers to ParentViewController. Then call didMoveToParentViewController: method.
//Controller1
Controller1 *c1 = [[Controller1 alloc] init];
c1.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self addChildViewController:c1];
[c1 didMoveToParentViewController:self];
//Controller2
Controller2 *c2 = [storyboard instantiateViewControllerWithIdentifier:#"c2"];
index.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self addChildViewController:c2];
[c2 didMoveToParentViewController:self];
c2.view.frame = m_contentView.frame;
[self.view addSubview:c2.view]; //It is in initial screen so set it right away
m_selectedViewController = c2;
//Controller3
Controller3 *c3 = [storyboard instantiateViewControllerWithIdentifier:#"c3"];
compare.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self addChildViewController:c3];
[c3 didMoveToParentViewController:self];
m_controllers = [NSArray arrayWithObjects:c1, c2, c3, nil]; //Hmm now i think this is not needed, I can access viewController directly from self.childViewControllers array
Then I implemented
- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
return YES;
}
Switching to child view controller is done with this code
if (value < m_controllers.count)
{
UIViewController *contentViewController = [m_controllers objectAtIndex:value];
contentViewController.view.frame = m_contentView.frame;
[self transitionFromViewController:m_selectedViewController toViewController:contentViewController duration:0 options:UIViewAnimationOptionTransitionNone animations:nil completion:^(BOOL finished) {
m_selectedViewController = contentViewController;
}
];
}
This should be enough. But i have got some issues with this so i send rotation messages to unactive Childs myself.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
for (UIViewController *vc in m_controllers)
{
if(vc != m_selectedViewController)
[vc willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
for (UIViewController *vc in m_controllers)
{
if(vc != m_selectedViewController)
[vc willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
for (UIViewController *vc in m_controllers)
{
if(vc != m_selectedViewController)
[vc didRotateFromInterfaceOrientation:fromInterfaceOrientation];
}
}
manually added
self.view.autoresizesSubviews = YES;
inside
- (void)viewDidLoad
and it solved the problem,
for some reason the value inside storyboard was not being used i guess
I'm a junior and I have been really struggling to get this to work, would really appreciate some help.
I am trying to build an App where you can scroll through different WebViews by selecting an item from a table in a popover (while the popover remains in place). Unfortunately, I can't get my scrollView to move when I select an item from the popover view.
I have set up a UIScrollView with page control in a main UIViewController. The scrollView is populated with (pageViewController) UIWebViews. The main UIViewController has a nav bar with a button, when the button is clicked it creates a Popover View. When I select an item from the table in the popover view I want my UIScrollView to scroll to a certain position (equates to a selected page), but the scrollView does not move.
The method below takes the value selected from the popover and uses the page number to determine where the scrollView should scroll to, but it doesn't work because at this point my scrollView is Null.
I can supply more code if needed.
main UIViewController.m code:
- (void)setDetailItem:(id)newDetailItem {
if (detailItem != newDetailItem) {
[detailItem release];
detailItem = [newDetailItem retain];
NSString *pgnum = [[NSString alloc] initWithString:[detailItem description]];
int pg;
if(pgnum == #"Page 1"){
pg =1;
}
if(pgnum == #"Page 2"){
pg =2;
}
if(pgnum == #"Page 3"){
pg =3;
}
[pgnum release];
pageControl.currentPage = pg;
[self loadScrollViewWithPage:pg - 1];
[self loadScrollViewWithPage:pg];
[self loadScrollViewWithPage:pg + 1];
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * pg;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
pageControlUsed = YES;
}
if (popoverController != nil) {
[popoverController dismissPopoverAnimated:YES];
}
}
This is how I triggered the popOverController
The infoButton is on the navbar.
The scrollView is NOT NULL in the infoButton
- (void)infoButton:(id)sender {
NSLog(#"Entering: infoButton");
// [self inspectView:self.view level:#""];
if (self.popoverController == nil) {
PopoverViewController *popoverViewController =
[[PopoverViewController alloc]
initWithNibName:#"PopoverViewController"
bundle:[NSBundle mainBundle]];
popoverViewController.navigationItem.title = #"Navigation";
UINavigationController *navController =
[[UINavigationController alloc]
initWithRootViewController:popoverViewController];
UIPopoverController *popover =
[[UIPopoverController alloc]
initWithContentViewController:navController];
popover.delegate = self;
[popoverViewController release];
[navController release];
self.popoverController = popover;
[popover release];
//NSLog(#"User pressed the info button");
}
[self.popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; }
UIPopover, being neither the most obvious class to use memory-management wise, nor the most stable, does not require you to release it before you present it. In fact, doing so causes it to throw a fatal exception! Popovers should be released after they are removed from the screen, and/or in -dealloc.