show different controllers for one tab depending on some condition - ios

When user taps on Favourites tab, I need to show:
Introduction of how to add favourite, if there is no favourite
Otherwise show the list of favourites
So when user taps on the tab button, I need to check if there is any favourite then decide which controller to use, how do I do this?
Thanks!

If the introduction is static, with no significant user interaction, you can place the introduction into a subview that is on top in the view containing the list of favorites. Set its frame size to cover up the favorites list. (It will be dismissed by the user with the code below.) Call this the introductionView. One way to put the introductionView on top is to add that subview last when you create the list-of-favorites view.
In your view controller for your list of favorites, go to viewWillAppear and add these lines:
(If there are already favorites, this assumes the user has been through the introduction.)
if (*some test whether there are already favorites on the list*)
introductionView.hidden = YES;
else
introductionView.hidden = NO;
Add some code to run when the user presses the dismiss button
- (void) dismissHit{
introductionView.hidden = YES;
}
This will always show the introductionView when the favorites tab is hit, unless there are some favorites already on the list. Read the UIView class reference and the UIViewController class reference. Look at the methods listed to get a better feel what this is doing.
Good luck.

Related

Objective C: show textfield and textview input in label on next view?

So i've seen many questions alike mine, but all don't have the working answer, or have vague answers (and none of them marked as correct).
I have two ViewControllers:
ViewController #1 has 4 textFields to which there are pickerViews attached in order to choose an option to fill in the textfield.
Also there is 1 textView in which the user can use the keyboard.
To sketch the scenario: Label states: 'Pick a color:' User clicks on the textfield (pickerView shows up full of names of colors) user selects 'red' and the picked choice shows up in the textfield below the label: 'pick a color'.
Then when all textfields and textview are filled in, the user clicks save. In which the save button redirects the user to the 2nd ViewController.
ViewController #2:
This is where i want the input (of the textFields and textView) to be shown in the labels(if this is the correct usage). Since this is where the user will see list of the chosen answers. However i cannot manage to get this working.
What do i need to do in order to achieve this?
Also i'm still learning. Please bear with me.
Thanks in advance.
In general this site is not well-suited to "Tell me how to do XYZ" type questions. It's intended for getting help with code you have already written. You're new, though, so I'll take pity on you.
You should post the code that you have, showing how you get from view controller 1 to view controller 2.
I'm going to assume that you have a segue from view controller 1 to view controller 2.
(You should probably have code that disables your send button until all 4 text fields are filled in with valid colors.)
Anyway, let's assume that your send button triggers a segue, either directly, or in an IBAction that triggers a segue through a call to performSegueWithIdentifier.
You need to define properties for your 4 color strings in view controller 2.
Then, add a prepareForSegue method to view controller 1 if you don't have one already. In prepareForSegue, make sure the segue matches the segue identifier that invokes view controller 2 (good idea even if you only have 1 segue now, since you might add more segues later.)
ViewController2 *vc2 = (ViewController2 *) segue.destinationViewController;
Assuming it's the right segue, get a pointer to the destination view controller and cast it to the type of ViewController2 so you can refer to your color properties.
Then use code like this to pass the colors to view controller 2:
vc2.color1 = myColor1TextField.text;
vc2.color2 = myColor2TextField.text;
vc2.color3 = myColor3TextField.text;
vc2.color4 = myColor4TextField.text;

Enable editing mode for tableView when button is pressed

This has probably been asked before but I'm new to iOS Development and when I found confused me. I have a tableView and want to allow the user to tap a button that says "Edit" and they can delete items. I also want the edit button to become a "Done" button, which will stop edit mode. (The user can add data into the tableView from another option, which I will probably need to research how to do.) I don't have a storyboard as I built the app in an app called Interface. Everything is all in code.
The UIViewController class provides a method that gives you the standard Edit/Done button. You can do something like:
self.navigationItem.rightBarButtonItem = [self editButtonItem];
This standard button is setup to call the setEditing:animated: method. When used with a UITableViewController, the table view is automatically toggled between regular and edit mode along with the view controller.
There are plenty of specific table view delegate and data source methods you need to implement on top of this to facilitate actual table editing but using this standard button at least easily lets you toggle in and out of editing mode.
You will need to add the UITableViewDelegate methods.
I presume the 'Done'/'Edit' Button is the same in some place such as your UINavigationBar?
You will have to manually change the title for the button.
Remember to set your ViewController as the delegate for tableview too.
This delegate method informs that you wish to have the table eidtable.
– tableView:editingStyleForRowAtIndexPath:
This method tells you you will start editing:
– tableView:willBeginEditingRowAtIndexPath:
(hint: change button title here)
Likewise this tells you editing is done:
– tableView:didEndEditingRowAtIndexPath:
(hint: change button title here)

What are the "First Responder" and "Exit" boxes purpose in the storyboard editor?

In the XCode IDE, at the bottom of the view controller in the MainStoryboard editor, are two boxes: First Responder, and Exit.
I know what a firstResponder is programatically within the code, but in the storyboard editor, I can't seem to do anything useful by it.
Am I able to use the first responder in this area to somehow set the first responder of the view? I'd like the first textfield to be active on load and I have tried right+click and dragging to no avail. I know I can set it programatically in the viewDidLoad method, but is there some way of doing it here?
And what is the green Exit for?
There are no good answer for this question, so I am posting my answer:
From here:
Note: You probably won’t be using the First Responder very much. This is a proxy object that refers to whatever object has first responder status at any given time. It was also present in your nibs and you probably never had a need to use it then either. As an example, you can hook up the Touch Up Inside event from a button to First Responder’s cut: selector. If at some point a text field has input focus then you can press that button to make the text field, which is now the first responder, cut its text to the pasteboard.
Edit:
1) First Responder is very useful if you are using text fields with keyboard notifications. I use it to make keyboard disappear, make an outlet to variable currentFirstResponder of your class, and in viewWillDisappear:
[self.currentFirstResponder resignFirstResponder];
2) You can read about unwind segues ("Exit" box) here
I've never used it and probably never will but you can assign an object to be the first in line to receive the events from the UI.
I suppose you could be creating a UIView subclass and add it in to a UIViewController but you actually want some other object to receive and process the events other than the UIViewController you are adding it to.
I found this link which kind of explains it a bit better.
First Responder: The First Responder icon stands for the object that the user is currently interacting with. When a user works with an iOS application, multiple objects could potentially respond to the various gestures or keystrokes that the user creates. The first responder is the object currently in control and interacting with the user. A text field that the user is typing into, for example, would be the first responder until the user moves to another field or control.
Exit: The Exit icon serves a very specific purpose that will come into play only in multiscene applications. When you are creating an app that moves the user between a series of screens, the Exit icon provides a visual means of jumping back to a previous screen. If you have built five scenes that link from one to another and you want to quickly return to the first scene from the fifth, you’ll link from the fifth scene to the first scene’s Exit icon.
More here
You don't see this very often, where a deleted answer is actually correct, and the comment (likely influencing its deletion) on it is totally wrong! I'll try and improve on it.
Usually the IBAction you want to hook up to a button is in the view controller containing the button. However if the IBAction is in a different controller, e.g. a parent controller then drag from the button to the First Responder object and you are able to select the IBAction in the parent controller!
As the hidden answer states, how this is implemented is the action is sent to nil, which has the effect of the responder chain (i.e. view hierarchy) being searched for the action, as follows:
[UIApplication.sharedApplication sendAction:#selector(nextObject:) to:nil from:self forEvent:nil];
An example is a custom UITableViewCell. Add a UIButton to the cell but you want the action to go up to a View Controller that has an embed segue to a UITableViewController. Drag the touch up instead action to the First Responder and select the action in the container view controller. In the action to find the indexPath simply loop the visibleCells and check if the sender is isDescendantOfView:
- (IBAction)cellButtonTapped:(id)sender{
for(UITableViewCell *cell in self.tableViewController.tableView.visibleCells){
if([sender isDescendantOfView:cell]){
NSIndexPath *indexPath = [self.tableViewController.tableView indexPathForCell:cell];
NSLog(#"tapped %#", indexPath);
}
}
}
Another example could be a reload button: say your first view controller shows an downloaded item with an IBAction to reload it to get the latest data, then your child controller shows some detail, but you also want them to be able to reload the main item from within the detail, just add a button in the detail and drag its action to First Responder and select the reload IBAction in the parent controller. This allows you to hook up buttons to parent actions with no additional code like delegate methods!
For this to work the action needs to be in the responder chain hierarchy or it won't be found, you can read how the chain is built up in the docs. Also note if called from code the view needs to have appeared, viewWillAppear is too soon.

ios ignoring viewWillDisappear

I have a form on a tabbed view; I mark the form dirty of any of the fields have been changed and I want to pop up an ActionSheet with "save"/"cancel" if the form is dirty (in lieu of a "save" button). Is there any way to stop the view from disappearing (or being removed from the view stack) until the user responds to the ActionSheet being handled?
A couple of thoughts:
It's worth noting that Apple's Human Interface Guidelines (the HIG) explicitly discourages this practice. They suggest that apps should "ask people to save only when necessary" because people "should have confidence that their work is always preserved unless they explicitly cancel or delete it." Perhaps in your case, it's important to have this feature, but it's generally discouraged.
An alternative, if you want to give users the chance to revert to old settings is to provide an "undo" button, that way, you honor the HIG and effectively auto-save, but you also give the user to explicitly revert to prior values if they really need to.
As others have noted, the notion of prompting to save or discard on viewWillDisappear doesn't quite work. It's logically too late in the process. viewWillDisappear could be called for too many reasons, many of which are not under your control, and it's not copacetic to fail to return promptly to that method, to introduce new user interface elements, etc.
If you really, really need the "save" vs. "cancel" user interface, then that lends itself to more of a modal interface (or push a new view controller that you have to pop off to return to your tab bar view controller) with save and cancel buttons rather than a tab bar interface. E.g. your tab bar view could show current values, you tap on an "edit" button, which pushes new view with save and cancel buttons. We don't know enough about your app to be able to advise whether this is logical in your case or not. (For another approach, see enabling edit mode in view controller.)
You can't stop the view from disappearing once the app has progressed to the point where viewWillDisappear: has been called. The thing to do would be to create a function like:
- (void)saveAndClose {
//Display sheet asking user what they want to do
}
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
{
if (buttonIndex == 0) // 0 or whatever the index of your save button is
{
// Perform save functions
}
[self dismissModalViewControllerAnimated:YES]; // or pop the view controller if appropriate
}

How to increment a selected table row on iPhone

If someone was able to help me with the following, that would be great!
So here is what I'm trying to do. My app is basically a rss reader. The topics of the rss entries are displayed in a table view. Tapping on an entry opens a web view which displays the whole story. To this web view I have added a toolbar with up and down arrows so the user would be able to jump to the next/previous story without leaving the web view and having to tap another entry in the table. My problem is that I have no idea how to archieve this. Maybe this is related to the structure of my app. My guess is that I have to somehow increment the selected row on tapping the button.
As I said, maybe the code is a bit complicated, so I've posted the whole project here: http://www.schimanke.com/flo.zip It would be great if someone could have a look and tell me what to do.
What you need is to know which row is currently selected on your model. Since you have a reference to the model from your webview, that's easy:
int row = [mainModel.blogEntries indexOfObject:mainModel.selectedBlogEntry];
So all you need after that is to show the next (or previous) entry. Based on your code, it goes like this:
- (void) showNextPrevEntry:(int)increment usingTheOldController:(BlogEntryController *)controller {
int row = [mainModel.blogEntries indexOfObject:mainModel.selectedBlogEntry];
if (row+increment<[mainModel.blogEntries count] && row+increment>=0) {
mainModel.selectedBlogEntry = [ mainModel.blogEntries objectAtIndex:row+increment];
controller.mainModel = mainModel;
[controller viewDidLoad];
}
}
I don't think it's healthy to call viewDidLoad. Maybe you need another method just for updating the current loaded view and call that from your viewDidLoad. Also I'm not sure why you are using notifications for handling the button presses from the toolbar, but it works. :)

Resources