Adding and Removing UIBarButtonItems to UINavigationBar from Multiple Views - objective-c

I currently have a Main Window set up as a UINavigationController (also is the root view controller), and I have two views. The first view is the login screen, and the second screen is a table view screen. What I would like to have happen is to show different UIBarButtonItems based on what screen is showing up. For instance, when the logon screen is being displayed, I want a left button on the navigation bar to be displayed (more specifically, it'd be a Settings button before logging in). Once the user logs in, I want the left button to say "Logout" and the right to be a reload button. I've tried programmatically adding the buttons, but they won't show up. Any suggestions?
Also, I've gotten most of this done in IB, but I feel like it would probably be easier to add these buttons programmatically.

All subclasses of UIViewController have a property called navigationItem. While it is readonly, you can alter its properties. So in LoginViewController, you would do self.navigationItem.leftBarButtonItem = /* Code to create the bar button */ and likewise within the TableViewController. Let me know if you need more detail.

Related

View Controllers, Popup buttons, AppDelegates, Status Menus, and headaches

This is kinda long but I want to give as many details as possible.
I have created a status bar app. One of the things I've done is made it to where there is a "Settings" menu item that if you click on, an NSWindow pops up with 5 different buttons -- these buttons are tied to their own custom NSViewController so that if you click them, the View Controller changes, but the window remains the same, just like any other StatusBar app.
On one of the view controllers is a popup button with several user selectable options. If I add a button to the specific VC (view controller) and link that to an ibaction that pulls the selected index of the popup button, it works just fine (i.e. I select item 2, it logs item 2).
Now here's where things get. . . odd. I've created a submenu that would in theory allow the user to quickly change the selected item of the popup linked to my custom view controller. Think of this submenu as being labeled 1-4 and clicking one of those items would change the index of the popup button, however every time I try this and follow it up with a NSLog to ensure the button has changed, it ALWAYS reads zero, in other words, it NEVER changes.
Here's what I tried.
Just like with every other view controller I've ever used, I create a new object of my view controller (alloc, init), and reference the popup button object that i've created as a property. This compiles just fine, but returns only zero no matter what is selected.
I've tried calling the method that I know works (the button that is on the view controller containing the popup), but again, this returns only zero no matter what is selected.
Any advice would be greatly appreciated.
tl;dr: can't change a popupbutton on a view controller from the app delegate or nsstatusmenu item, it just always returns zero.
EDIT: I have found a work around since I can communicate to my app delegate just fine, I created an int property and set it to zero. From there, whenever my popupbutton on my VC changes, I change the value of the app delegate int property and just ensure that whenever the nib launches, it set's the selected item to the app delegate property. I feel there has to be a more straight forward way to just get the value of the popup and change it from the app delegate.
EDIT 2: Some code as requested. I realized I needed to point the the view controller by using initwithnibname from the app delegate and then load the view. Doing so allows me to pull the first object in the popup button, any subsequent changes are not recognized unless I do so via my test button on the view controller itself. Also, I'm adding values to my popup in my awakefromnib in the view controller.
searches_VC = [[Searches_ViewController alloc] initWithNibName:#"Searches_ViewController" bundle:nil];
[searches_VC loadView];
NSLog(#"Selected Title: %#",[[searches_VC profilePopupOutlet] titleOfSelectedItem]);

How Can I Change UIImages in a ScrollView based on a User's Input

Okay gang, I'm scratching my head on how to accomplish this one so I wanted to put it out to the world at large.
Essentially what a client wants is a way to toggle PART of a view based on whether the user selects a "Yes" or "No" option. My question is how would I go about accomplishing that?
Allow me to provide some more details. Within this specific app resides a form (a form with custom text fields, picker views, switches, sliders and other UI elements) that have all been laid out in a Storyboard, then programmed to function. About 3/4 of the way down this form, the user will be greeted with a "Yes" or "No" option and a button for each. The trick is that each view needs to have its own UI elements (text fields, sliders and buttons) appear ONLY when one of the options is selected and only BELOW the "Yes" or "No" option (all the elements above it need to remain, stay in the same place and hold the information the user enters).
An example : If the user hits the "Yes" button, below it 3 lines of text followed by a UIButton and Text Field would appear. Underneath this, other navigation buttons which navigate to other ViewControllers would appear. However, if the user hits the "No" button , all of those items I mentioned a moment ago would need to disappear, and instead a different set of text fields, labels, buttons and background image would need to appear. The navigation buttons will also need to link to other ViewControllers, different from the buttons in the "Yes" option. At this point I suggested to the client that a Navigation controller rooted at the bottom of the screen would be a good idea, but they are vehemently opposed to this and instead want the navigation options to be "dynamic" (or change according to which option is pressed, "Yes" or "No").
I have thought to attempt this programatically by simply using each button to load in a different image, this works just fine. The hitch then becomes twofold;
1) When I attempt to load the other UI elements that I get no way to lay them out in a storyboard and thus they appear in sporadic locations and
2) All this needs to be contained within a scroll view, which ALSO needs to change its size depending on how much space is needed below the yes and no option. Naturally the "Yes" section is 3 times smaller than the "No" section.
So, any ideas on how to make all this happen? I should mention at this point that the client also does not wish to simply navigate to a different ViewController, they very much want all this to occur on the same screen. I wish I had some code to share but we are still in the "design" aspect of this project and as such, very little code has been written. Any advice will be much appreciated as I've never been greeted with this type of build request before.
Create a UINavigationController object and set your view(say yourViewController) where your Yes and No buttons exist as a root view controller as below
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:yourViewController];
Now when user press YES/NO button on yourViewController view than you can programmatically create all controls text field and buttons and set frame according to your view. like
UITextField *txtField = [[UITextField alloc] initWithFrame:CGRectMake(enter frame accordinglly)];
[self.view addSubview:txtField];
same you can add more controls like buttons or any other controls.
after that when user press any the button(on which you want another view to display) you can push other view in the navController as below
[navController pushViewController:otherViewController animated:YES];
you need to keep track of navController in your yourViewController
when you want to go back just pop view from navController
[navController popViewControllerAnimated:YES];
PS: please be watchful for memory deallocation as well.

Make a button to go back to the first of several screens

I am creating an app which has five screens, and each screen has a button called "Home Button".
When the user presses the home button, the user should go back to very first screen.
How can I do this?
I am adding each screen over another screen like this:
[self.view addSubview:myview];
UINavigationController has an array viewControllers of pushed viewControllers.
You can manipulate this array instead of pop commands.
You should have used an existing controller to manage your hierarchy between your views. But anyway, I think what you can do is calling removeFromSuperview on each subview and adding again your very first view. You can do this with :
[self.view.subviews makeObjectPerformSelector:#selector(removeFromSuperview)];
Or you can also tag the views as you add them, and remove only the tagged views to avoid removing your first view from superview.

Problem tabbing to field when adding and removing view

I have an scope bar containing a NSSearchField. The bar can be shown and hidden using a menu item. I generate this bar by creating a new NSViewController (and loading a new view from the XIB). When the bar is shown, I do a addSubview: to the window's contentView; when the bar is hidden, I do removeFromSuperview to the view within the view controller.
If when I launch the app and the bar is already opened, hitting tab toggles between the main view within the window (a table view) and the search field in the scope bar. If I launch the app and the bar isn't already shown, once I do show the bar I can tab from the table view to the search field, but not the other way.
Once I remove the scope bar for the first time, then show it again, I can no longer tab between the search field and the table view, no matter which view is currently selected.
Is there something I need to be doing besides addSubview: and removeFromSuperview? I can't wrap my head around why this won't work, and especially why I get different behaviors if the bar is shown on launch or not.
You need to set the nextKeyView of both views if you want to control what happens when you hit the tab key.
[yourTableView setNextKeyView:yourSearchField];
[yourSearchField setNextKeyView:yourTableView];
However, you need to be careful because you can break the automatically constructed key-view loop. This article has more detail on how to handle this situation.
I was able to get the desired behavior by setting setAutorecalculatesKeyViewLoop: to true on the views' window.

Objective C: How to reload tableview immediately after switching tabs?

I have 2 tabbars in my tabbar controller. I am currently in the second tabbar, after I click on a 'done' button, the tabbar controller needs to switch to the first tab and auto refresh the tableview in it.
I am able to execute on the first part
//Switch to the first tab's view
self.tabBarController.selectedViewController
= [self.tabBarController.viewControllers objectAtIndex:0];
However I need some advise on how to refresh the first view's tableview immediately after the switch is made. Any advise is appreciated.
EDIT: Updated requirement
Note: I do not want the view in the tabbar to reload everytime someone clicks on the tab. The reload should only happen in tab 1's tableview when
1) User is in tab 2
2) User clicks on 'Done button' in tab 2
3) App switches to tab 1 + Reloads the tableview in tab 1
Rationale is that the user will update some information in tab 2 which can only be viewed in tab 1. I want the user to be able to view the updated info immediately after switching to tab 1.
You could just do [tableView reloadData] in the first view's viewDidAppear: method?
EDIT: Editing to add additional data.
General caveat here, Apple tends to frown upon having custom UI Patterns like this. I'm not sure what your app is trying to do here, but you should mostly stick with switching tabs only if the user explicitly clicks on that tab. Have you looked at modal view controllers if you want to present a screen and get some data back, instead of having it in a tab bar?
If not, I guess you could have a solution where the first tab is a delegate of the second tab. When the button is clicked, you could call [delegate doneBtnClicked:] so the control shifts to the first tab. In that function, you could use the setSelectedIndex: to your current tab and call reloadData: on the table view.
You can send NSNotification after
pressing done button on second tab
and handle this notification on first tab controller.
So, create a DONE Button as a UIBarButtonItem, and in it's IBAction, do the following.
For reloading the tableView for the view in the first tab, put that tableView as that class' property , and reference the class like #class class1 , and create an object as a property class1 *object1 for View1 (Tab1) in the class for View2 (Tab2), and access the array1 using object1 like
[class1.object1.array1 reloadData];
And for bringing the view to tab one, use
self.tabBarController.selectedIndex = 0;
Thats pretty much it !
Alternatively you can also use a singleton class for this purpose.