PopViewController in Tabbar application - iphone

I am working on a Tab-bar application.
TAB-BAR CONTROLLER
|
_______________________________________________________
| | | |
View 1 View 2 View 3 View 4
| |
SearchingON Detail View
Problem 1 :I have a button (Let say Sign Out), On click of The button which is on View 4, I want to pop the Detail view of View 2.
So that after new login new user should not reach to detail veiw.
I have tried :
if ([[NSUserDefaults standardUserDefaults] valueForKey:#"IsChattingON"])
{
ChatDetail *chat = [[ChatDetail alloc] initWithNibName:#"ChatDetail" bundle:nil];
[chat BackButtonClicked:nil];
}
and in Detail View back Button my code is :
-(IBAction)BackButtonClicked:(id)sender
{
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"IsChattingON"];
[self.navigationController popViewControllerAnimated:YES];
}
Here User Defaults having Bool value whether Detail View is open or not.
Problem 2 : I am applying Search on View 1's Table View and want to remove Search if View 4 SignOut button is clicked. I want to refresh my View 1 if Signout button of View 4 is clicked.
For removing Search I have done this code but not getting the desired results.
PeopleController *People = [[PeopleController alloc] initWithNibName:#"PeopleController" bundle:nil];
People.isSearchingRecords = NO;
I have Searched so far about popViewControllers but cant find this scene. Pls let me know how can I achieve this functionality.

You should not allocate a new view controller when the user taps on logout,
instead you should do the following
- (void) logOut
{
//get the view 2
//you should have a way to access view 2
[view2 closeChatView];
}
//On view 2 maintain a reference of chat detail controller
- (void) closeChatView
{
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"IsChattingON"];
//chat is the reference to the chat details controller
[chat.navigationController popViewControllerAnimated:YES];
}

I assume that you keep instance of navigation controllers in appDelegate then you can try this:
NSArray *viewNavStack = appDelegate.viewNavController.viewControllers;
if ([viewNavStack count] > 1) {
[appDelegate.overviewNavController popToRootViewControllerAnimated:NO];
}

Finally I got solution for Problem 2 :
I am setting a NSUserDefault BOOL to NO, and in ViewWillAppear I am getting that UserDefaults value whether searching is ON or not.
On click of Signout Button :
[[NSUserDefaults standardUserDefaults]setBool:NO forKey:#"SearchingON"];
and on View 1 :
isSearchingRecords = [[NSUserDefaults standardUserDefaults] boolForKey: #"SearchingON"];
if (isSearchingRecords)
{
self.btnSearchCancel.hidden = NO;
}else
{
self.btnSearchCancel.hidden = YES;
}
But cant find the solution of Problem 1 - to pop the view by another tab, if any one have any idea pls let me know !!

Related

how to populate an array or any object from one view controller to another when we present the view using story board

I have implemented my iphone app using story board
In my app *i need to present a view from one view to another view not the pus*h,
I have created a screen in story board xib for the second view .
i set up the connection for button in the first view to the second view with 'present' not pust.
Now i need to populate an array to the second view which was presented
i tried following ways but not work out
1:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UIButton *)sender
{
//Populate detail to BuyView mail page
if ([segue.id
entifier isEqualToString:#"BuyView"])
{
BuyViewController *destViewController = segue.destinationViewController;
destViewController.itemDetailsArray = [_itemDetailsArray objectAtIndex:sender.tag] ;
}
}
2:
- (IBAction)buyItemClick:(UIButton *)sender
{
BuyViewController *destViewController = [[BuyViewController alloc] init];
destViewController.itemDetailsArray = [_itemDetailsArray objectAtIndex:sender.tag] ;
}
On top of what #rdelmar has stated you are passing an object of which may or may not be an array.
Which in turn would mean
destViewController.itemDetailsArray
Would be pointing to an object which may not be an array.
I think what you want to do is
destViewController.itemDetailsArray = _itemDetailsArray;

iOS - incorrect badge value retrieved from tab

I'm trying to retrieve the value displaying for a specified tab. It was working before and it stopped for some reason? The int current_badge = line on the code below is where the badge value is fetched and returns zeros no matter what the badge value actually is. I'm in a viewcontroller segued off of a uitabcontroller. Anyone have any thoughts on what I'm doing wrong?
UPDATE: It appears to be because I'm in a viewcontroller off of a tab controller. Move the same code into a tab viewcontroller and it works fine. Is there a better way to determine the badge value in a tabcontroller when segued out of it?
-(void)badgeUpdate:(int)tab:(int)dayspan
{
// getting the current badge amount
int current_badge = [[[super.tabBarController.viewControllers objectAtIndex:tab] tabBarItem].badgeValue intValue];
// testing for badge level
if (current_badge > 0)
{
// testing for updates on tab for dayspan or longer
int updates_waiting = [self updatesWaitingCheck:tab:dayspan];
if (updates_waiting > 0)
{
// setting new badge level on tab
[[[[[self tabBarController] viewControllers] objectAtIndex:tab] tabBarItem] setBadgeValue:[NSString stringWithFormat:#"%d", updates_waiting]];
}
else
{
// turning off badge display
[[[[[self tabBarController] viewControllers] objectAtIndex:tab] tabBarItem] setBadgeValue:nil];
}
}
}
The controller for that tab is likely being deallocated when you switch away. I would suggest moving the logic to determine the current count out of the view layer, and into a higher level controller that persists across all tabs. Otherwise, you'll run into the problem you're seeing.
Most of the time, if you're looking for a data value in a view object, rather than in a controller or model somewhere, you're working against the framework and you'll run into problems like this.

ViewController and SegmentedControl

I have ViewCtrl1, and StartBtn:
-(IBAction)startbtn
{
ViewCtrl2 *vc2 = [[ViewCtrl2 alloc]init];
[self presentModalViewController:vc2 animated:YES];
}
I have also ViewCtrl2, UISegmentedControl, and ExitBtn:
- (IBAction)exitIt {
[self dismissModalViewControllerAnimated:YES];
}
If in ViewCtrl2 i select segment 2, or 3. When I press ExitBtn, will show ViewCtrl1, and if I press StartBtn from ViewCtrl1, my ViewCtrl2 shows default selected segment, not changes that i made recently.
How can i fix it?
You creating new vc2 each time and of course it shows default values. Initialise it once and reuse.

Act on click of a button on the Nav Bar for moreNavigationController -- Can't pushviewcontroller

Okay, here is my issue: My app has a display of categories in the tab bar at the bottom of the iPhoneOS screen. This only allows 5 categories before it presents the MORE button. I have over 25 (please do not answer this by saying: "Rethink your application...etc" -- that was rudely said before. They are food, drink, etc categories and cannot be changed). I want to allow the user to put their favorites on the home page. The Apple moreNavigationController editing system only allows 20 tab bar items to be rearranged due to space constraints on the editing page. This is not enough so i need to implement my own Editing screen. I set the rightBarButtonItem to nil and created my own. Using NSLog, i can see the "click" happens when clicking the EDIT button, but I cannot push using pushViewController. Nothing happens. I think it has something to do with the navigationController I am addressing...but i am not sure. ps: This all happens in my App Delegate which DOES act as both UITabBarControllerDelegate & UINavigationControllerDelegate.
I tried to do the following:
- ( void )navigationController:( UINavigationController * )navigationController_local willShowViewController:( UIViewController * )viewController_local animated:( BOOL )animated
{
UIViewController * currentController = navigationController_local.visibleViewController;
UIViewController * nextController = viewController_local;
// Do whatever here.
NSLog(#"Nav contoller willShowViewController fired\n'%#'\n'%#'\nThere are currently: %d views on the stack\n",currentController,nextController,[self.navigationController.viewControllers count]);
if ( [nextController isKindOfClass:NSClassFromString(#"UIMoreListController")])
{
UINavigationBar *morenavbar = navigationController_local.navigationBar;
UINavigationItem *morenavitem = morenavbar.topItem;
morenavitem.rightBarButtonItem = nil;
NSLog(#"Is a UIMoreListController\n");
UIBarButtonItem *editTabBarButton = [[UIBarButtonItem alloc]
initWithTitle:#"Edit"
style:UIBarButtonItemStylePlain
target:self
action:#selector(editTabBar:)];
morenavitem.rightBarButtonItem = editTabBarButton;
[editTabBarButton release];
}
}
This works to place an EDIT button at the top right of the screen -- mimicking Apple's look and feel... but when that button is clicked, you cannot exit the darn moreNavigationController.
I have tried many things. UIAlerts work, etc...but pushing (or popping -- even popping to root view) a view controller on the stack does not.
- (void) editTabBar:(id)sender {
NSLog(#"clicked edit tabbar\n");
NSLog(#"Total count of controllers: %d\n",[self.navigationController.viewControllers count]);
TabBarViewController *tabBarViewController2 = [[TabBarViewController alloc] initWithNibName:#"TabBarView" bundle:nil];
tabBarViewController2.navigationItem.title=#"Edit Tab Bar";
[self.navigationController pushViewController:tabBarViewController2 animated:YES];
[tabBarViewController2 release];
NSLog(#"finished edit tabbar\n");
}
If you click the edit button on the moreNavigationController's display page, you get the log entries like expected AND (this is strange) the views on the stack climbs -- but no page change occurs. I marked it down to not using the correct navigation controller...but I am lost on how to find which one TO use.
this is a weird one too. In the edit function if i just do this:
- (void) editTabBar:(id)sender {
self.tabBarController.selectedIndex = 0;
}
It DOES take me home (to tabbarcontroller 0)
BUT doing this:
- (void) editTabBar:(id)sender {
[self.navigationController popToRootViewControllerAnimated:YES];
}
does not work.
Does the moreNavigationController have some special quality that screws with the rest of the system?
I would try reimplementing the whole "More" functionality from scratch. In other words, store the four home tabs in your user defaults and add a dummy fifth tab that switches to your own complete reimplementation of the more view controller stack.
You could even write a lightweight subclass of UITabBarController that handled this for you.
UITabBarController is evil, so I wouldn't be at all surprised if MoreController had some special properties, too.
I have had success intercepting the More Controller in shouldSelectViewController to change the data source; you may be able to find some workaround there.
PS I am inclined to agree that you could consider redesigning your app so that you didn't need an unlimited number of viewControllers attached to the tab bar just to select categories; you might have better luck using a tool bar with a single, scrollable, custom view in it. If that's really the best way of picking categories for your app, of course.

Is it possible to select a row in a **previous** UITableview

Is it possible to select a row in a previous UITableview.
I provided image samples to get a more clear picture of what is happening exactly.
http://img186.imageshack.us/img186/933/picture8a.png
http://img405.imageshack.us/img405/9327/picture9d.png
http://img200.imageshack.us/img200/5386/picture10thm.png
At the morning workout screen , one can select a row and behind it so it will play a Movie.
If the movie plays you can press the secondbutton and it will take you to the final table.
If you press the backbutton you will simply return to the previous screen.
Now here is where my problem lies.
If i'm in my final screen after pressing the secondbutton and I press on the backbutton it would be great if it could play the previous video( in other words the video connected to the previously selected cell)
So if it's possible for me to create a function or some sort of action that can actually select the previously selected row from the first field ( for instance Lunge Forward in this example ).
perhaps with some like
previousRow = [ self.tableView indexPathForSelectedRow];
[self tableView:[self tableView] didSelectRowAtIndexPath:previousRow];
just doing something there
Even if it's not possible I would appreciate it if someone would let me know.
edit:
Here is some code behind the cell when it's going to play a video
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the dictionary of the selected data source.
NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
//check to see if video must be played
NSString *playVids = [dictionary objectForKey:#"playVids"];
finalscreen = [dictionary objectForKey:#"finalScreen"];
if(playVids == nil )
{
if(CurrentLevel != 0 )
{
if( finalscreen == nil )
{
NSString *movies = [dictionary objectForKey:#"movieID"];
NSURL *movie = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:movies ofType:#"m4v"]];
theMovie = [[MPMoviePlayerController alloc] initWithContentURL:movie];
[theMovie setOrientation:UIDeviceOrientationPortrait animated:NO];
[theMovie setScalingMode:MPMovieScalingModeAspectFit];
theMovie.backgroundColor = [ UIColor whiteColor];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:theMovie];
[theMovie play];
[self getToolBarStuff];
lblTitle.text = [dictionary objectForKey:#"Title"];
[[[UIApplication sharedApplication]keyWindow]addSubview:toolbar2];
[[[UIApplication sharedApplication]keyWindow]addSubview:imageView];
[[UIApplication sharedApplication]keyWindow]addSubview:lblTitle];
}
}
else
{
WebViewController *web = [[WebViewController alloc] initWithNibName:#"WebView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:web animated:YES];
[web release];
}
}
else {
//Prepare to tableview.
rvController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:[NSBundle mainBundle]];
//Increment the Current View
rvController.CurrentLevel += 1;
//Set the title;
rvController.CurrentTitle = [dictionary objectForKey:#"Title"];
//Push the new table view on the stack
[self.navigationController pushViewController:rvController animated:YES];
rvController.tableDataSource = Children;
[rvController release];
}
}
I get my info/feeds from a dictionaryfile and also different tags in my dictionary tell my tableview when to play the video and when not( playVids ).
so to be exact I have a start screen which brings you to a second screen and that one brings you to the morning workout screen and from there if you click a cell it will play a (different with every cell) video. I can't use the standard design from apple(with the backbutton above) since this assignment specifically asks to use their own design.
That's the reason why i created my own tabbar and backbutton.
My backbutton looks like this
-(void)back_clicked:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
CurrentLevel--;
switch( CurrentLevel ) {
case 0;
[toolbar removeFromSuperView];
default:
break;
}
}
So if I'm in the last screen I just pop that screen to return to my previous one( the morning workout). And what actually has to be done is pop that screen and play the last video. I thought I could do that by popping the last screen and then selecting the previously clicked cell in morning workout.
Any thoughts on that.
I am not sure I understand your problem exactly here. Can you show a bit more code? You have 3 view controllers, right? Are you using a standard navigation controller pattern with push/pop to get from one to the other? It looks like maybe you aren't since the buttons are in an odd layout.
If you are then pressing the back button can just pop view 3 and go back to view 2 naturally (it will still be there, so the video should still be playable) so I don't see why you need to mess with the table in view 1 in order to find that and make it show again. You should just be able to hook into viewWillAppear and do the same thing you did when coming from view 1.
And if you aren't using a standard navigation controller pattern then maybe this is the problem. From a UI perspective you probably should do that anyway - people will expect a standard back button in the title bar.
I am pretty sure your problem is soluble anyhow - you can always pass object references from one view to the other when creating them for example - but I don't think you need to resort to the method you have in mind.
edit: reading the additional detail I see you are indeed using push/pop. So you have a stack of views, and when one is popped it uncovers the one beneath it, right? It should therefore be possible to do what you want by implementing the viewWillAppear or viewDidAppear methods in your controller. When your final screen is popped, if I understand correctly it will uncover the view which is able to play the movie. Your viewcontroller will get the viewWillAppear / viewDidAppear messages in that case - by maintaining state and receiving those messages you can then implement logic to decide whether or not you need to play the movie. Rather than call the didSelectRow. method again you could perhaps put the movie play stuff in its own method so you can call from either viewDidAppear or didSelectRow...
I also am not sure that I fully understand your question either but it sounds similar to a problem I was working on recently. Check out this post on using up down arrows to move through the parent table while in a detail view. My app was based on the same sample code so you should be able to get this to work without much trouble.
Up/down arrows in nav bar of detail view to page through objects in parent table