Xcode 4.5 Storyboard 'Exit' - iphone

I have just installed Xcode 4.5 for iOS6 support, and I have seen a new icon called 'Exit' in my Storyboard, listed under my view controllers along with 'First Responder' etc. A little green icon labeled 'Exit'.
I can find anything about it, nor work out how it can be used. How does it work?

This is called an "Unwind Segue". Unfortunately there's no documentation for this so far except a brief mention on XCode 4.5 new features list that states:
Unwind segues can allow transitioning to existing instances of scenes
in a storyboard
The good news is that there is a session from WWDC 2012 explaining those creatures (among other things).
You can just login to Apple's iOS Dev Center with your developer account details and then go to the WWDC 2012 videos page and watch "Adopting Storyboard in your App" (it's fifth from the top) The discussion of unwind segues starts at time 37:20.
Update:
Here is some more info on the subject from Apple's documentation
A placeholder object named Exit for unwinding seques. By default, when
a user dismisses a child scene, the view controller for that scene
unwinds (or returns) to the parent scene—that is the scene that
originally transitioned to the child scene. However, the Exit object
enables a view controller to unwind to an arbitrary scene.
(From iOS6 docset > General > Getting Started)
And here is a nice example of how you can implement one
Another Update:
Here is a technical note from Apple regarding this topic.

Imagine you have a sequence of views in your storyboard:
A -> ... -> Z
You want to have a button on view Z which allows the user to go all the way back to A.
So what you need to do is give the view that you want to back all the way out to, in this case, A, an instance method which is marked as a IBAction and takes in a single parameter of type UIStoryboardSegue *. The name of the method and variable don't matter. What you do within the implementation doesn't matter, either. Here's an example:
Obj-C:
In A's Interface (not Z's):
- (IBAction)cancelSignup:(UIStoryboardSegue *)unwindSegue;
In A's Implementation (not Z's):
- (IBAction)cancelSignup:(UIStoryboardSegue *)unwindSegue {
// Only "implemented" to satisfy a respondsToSelector: search.
// You can actually implement more stuff here, if you want, IE, if
// you need to reach out to a server to mention that this screen was
// returned to from a later screen.
}
Swift:
In A's source (not Z's):
#IBAction func cancelSignup(unwindSegue: UIStoryboardSegue) {
// Only "implemented" to satisfy a respondsToSelector: search.
// You can actually implement more stuff here, if you want, IE, if
// you need to reach out to a server to mention that this screen was
// returned to from a later screen.
}
Now, within your storyboard, control drag from an element on Z (IE, a cancel button) to Z's Exit. It'll scan through all of the views higher up in the view hierarchy which have an IBAction that accepts only a single UIStoryboardSegue * as an action and list them for you to pick from.
Hopefully this was more straight forward and helpful than the existing answers. I found that this link was particularly useful, so if there's a detail you're still fuzzy on after reading my answer, maybe this can help you (I tried to just condense all the useful info from this long article into a short answer):
http://www.freelancemadscience.com/fmslabs_blog/2012/9/24/advanced-storyboard-techniques.html

See also Cannot Connect Storyboard Unwind Segue which clarifies the requirements to bring the Exit icon to life. You must have, higher up in the view controller hierarchy, a method that is:
Marked as IBAction
Takes one parameter that is a UIStoryboardSegue*
If both those conditions are met, the Exit icon will see it and will permit you connect through to it by control-dragging from a button in the same view controller.
I have also now posted the world's simplest example here:
https://github.com/mattneub/Programming-iOS-Book-Examples/tree/master/ch19p638presentedViewControllerStoryboard (fixed 12 July 2013)
This shows how trivially easy it now is to segue to and back from a presented view controller, as opposed to all the work you had to do previously in order to hand info back and forth (the stuff in the template with a delegate and a protocol, all of which can now be deleted).

Just adding a slight subtlety to the requirements definition that might help. This is based on experimenting in Xcode 4.6. I found that it is specifically and only the declaring(!) of the method that enables the desired control-drag response from Xcode. Here's what I found to be the full requirements:
Marked as IBAction
Takes one parameter that is a UIStoryboardSegue*
You must have an action declared (but not necessarily implemented [meaning a method in the .M implementation section]).
It can be in any class's interface declaration, even the interface section of a .M, except the appdelegate class. (I did not see any dependency on its position in the controller hierarchy. You can add any old file and the system seems to aggregate all the methods that have the UIStoryboardSegue parameter and display them on the Exit icon's menu.) Note that the control-drag menu will even show you your method if the method is in the class of the scene you are manipulating in the storyboard editor, but it will appear without a colon and does not seem to trigger any action at runtime.
Example:
-(IBAction)anymethodname:(UIStoryboardSegue *)myvariable;

Related

The ultimate guide for writing parent view controllers

Short version
If I'm writing my own custom split view controller, what do I need to do to make the child view controllers work as expected?
For instance: to send viewWillAppear: and so on.
Long version
Background
A while back I answered the following question:
Switch between UIViewControllers using UISegmentedControl
With the following answer:
The right way to do it is to have the controller handling the UISegmentedControl add the views of the controllers as subviews.
[self.view addSubview:controller.view];
It's your responsibility to send viewWillAppear: and so on.
However, tc. pointed out that this is not as trivial as it sounds:
No. View controllers are not meant to be used like that - controller will miss out on a lot of the UIViewController magic that's taken for granted (namely -view{Will,Did}{Appear,Disappear}: and -shouldRotateToViewOritentation:).
By "magic", I'm referring to everything UIKit does behind the scenes. You also forgot -parentViewController (which is important for things like modal view controllers). Additionally, somewhere in the depths of UIKit, it automatically calls -viewSomethingSomething: for you, so you might get -viewDidDisappear: twice! (I can't remember the exact details, but there's another user reporting that all you need to do is call -viewWillAppear: and the other three methods happen automatically.) The key issue is that Apple doesn't document the "magic" or how it changes between OS updates.
Since then I've been thinking that one should compile a guide for what needs to be present in the parent view controller in order for the child view controllers to work as expected. Apple's documentation doesn't cover this and Google didn't help much either, so now I'm hoping to find this knowledge within the stackoverflow community.
I've written several controllers like this and they all seem to work, but I can't help but wonder if I'm missing out on important view controller magic.
I think the best solution is "don't do that". Instead of hoping that you can duplicate all of UIViewController's behavior without being rejected for using private API calls why not create non-UIViewController controller objects to manage your subviews? A "controller" is not necessarily a UIViewController.
At a minimum you would need to override or mix in replacement getters for parentViewController, splitViewController, navigationController, tabBarController, and interfaceOrientation (and probably also modalViewController). For each property you would need to make sure that any private setter called by UIKit still works as expected and any changes to those values made by modifying UIViewController ivars directly are also correctly reflected in your implementations.
You're also going to need to figure out how UIKit determines which UIViewController is currently active and should receive view controller lifecycle methods because you need to make sure that these are sent to your container view controller and not only to one of it's children.
You will also have to hope that you haven't just constructed a situation which isn't supported by any of Apple's view controller classes. For example will any of them break if they have a parentViewController but their navigationController, tabBarController, and splitViewController are all nil?
Finally you'll need to keep up with any changes to these private implementation details with every iOS release.

Beginner iPhone Development Questions

I have recently started to learn about programming for the iPhone and after going through numerous online tutorials and books (most of which tell you to write this here without offering any explanation as to why or how stuff is working) I still have many questions unanswered and it would be great if someone could help me clarify them.
Here goes:
1) In Interface Builder, what is file's owner, first responder, and a delegate, and where is the actual code that draws the view?
2) When using Interface Builder and you add components to the screen, I understand that Interface Builder doesn't automatically write the code for you, but how should I handle the events fired by the different components? From a best design practice view, should each component have its events handled in a separate file? (would such file be the component's delegate ?) or is it better to just make the viewcontroller class implement all of the interfaces of its components?
3) When creating a UITableView for example, and I define the function:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [listOfItems count];
}
I am saying that the object tableView of type UITableView has this callback function. Right? So in case I have another UITableView named MyTableView I should write a function as such:
- (NSInteger)MyTableView:(UITableView *)MyTableView numberOfRowsInSection:(NSInteger)section {
return [listOfItems count];
}
There's some big questions here and very hard to answer in a stack overflow post.
1)
A. What is the File Owner?
The nib is a file right? So what would own the nib file? Well the owner is whatever object you call initFromNib: on.
AClassName *theOwner = [[AClassName alloc] initFromNib:#"nibfile"];
A nib file is just a freeze dried object, a description of an object, a serialization of an object. The object is often freeze dried with a bunch of helper objects to it can be unfrozen and ready to go. Remind me of how Egyptian Pharaohs were buried with many of their servants and many of their possessions, they would be ready to go in the after life. The owner is the main object that has been frozen. In a frozen state (the nib file) the owner is frozen and you can't work with it. When you unfreeze by loading the nib file the main object that's unfrozen is the owner.
B. What is the First Responder?
When you interact with your program by touching the screen, shaking the phone, typing on the keyboard the program must respond to that event, many other frameworks call this handling the events or actions. The First Responder is the first object that gets to respond to the user's interactions. This will typically be the NSView that the user touches, which responds by redrawing itself and sending updated information to the View's Controller (Remember, NSView inherits from NSResponder - now you know why).
It's in the nib file so you can override the typical behavior. The Cocoa Framework is used for the Mac too so programmers might want to have a single object handle keyboard input rather than letting each view handling the keyboard input itself. This is rarely used in iPhone programs directly, because you typically want what the user touches to respond to user interaction (redraw itself) and pass on updates. So you can usually just ignore it in the nib file.
C. What is a Delegate?
What does a person do when they delegate? They tell someone else to do this job for them and report back. People delegate all the time. I delegate fixing my car to a car mechanic. I delegate cooking dinner to the cook at a restaurant I'm dining at. "Johnson, I need you to write that TMI Report for me" said my boss delegating to me for I was company expert on TMI. Classes in the code are no different.
The delegate in the Interface Builder is the Application's delegate. The UIApplication class is going to hand off lots responsibilities to it by sending messages to methods defined in the UIApplicationDelegate Protocol. For instance if your delegate implements the applicationDidFinishLaunching: method it'll receive a message after the instance of UIApplication has initialized and finished its startup routine.
D. Where is the drawing code?
Apple has provided with the Framework in classes like NSView, NSWindow, NSTableView and it's not open-source so you can't view the source code. But the reason the window launches and appears when your first run an application built on one of Apple's templates before adding your own code is due to what occurs in the file main.m.
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
The call UIApplicationMain(argc, argc, nil, nil) starts everything rolling. It loads in the nib file to unfreeze the UIApplication object and other objects in the nib file. Then it asks the application to start it's main loop. Once unfrozen the UIApplication object (the nib's owner) then tells it's MainWindow to display on the iPhone Screen and keeps the UIApplicationDelegate in the loop about what's going on.
Well that's my answer to 1). Took a while to write I hope it helps. One thing that really helped my understanding was: creating a new Window-based Application project, deleting the MainWindow.nib and then attempting to recreate it from an empty nib file, so that it functions the same way.
Here goes:
In Interface Builder:
The "file's owner" is the Objective-C class to which your interface belongs. Usually for a view controller this means the custom view controller subclass you're creating.
The "first responder" is mostly there for behind-the-scenes handling of events; it's used to figure out when your class and interface handle events, and when to pass them up the responder chain.
A "delegate" is a general term for any object which receives messages about the actions of another object. In Interface Builder, it can sometimes be used to pass actions around between objects, or can refer to the "app delegate," which is a class that exists in almost all iOS projects and receives messages about the behavior of the application itself.
To handle events from your GUI components, the generally accepted thing to do is to define a method with return type IBAction in your view controller implementation, then hook it up to an event from a component. Then when that event is triggered, your method is called. It's not usually necessary to break them out into a lot of separate files unless you have a very complex structure.
Not quite. If you have another table view, you can call it myTableView, but you should still hook it up to the same table view delegate and data source, and the method name doesn't change. Let's break the first part of this method signature down:
The (NSInteger) means this method returns an integer
The phrase tableView: is part of the method name, and shouldn't be changed. A table view will always call the method tableView:numberOfRowsInSection: for the information it wants, so changing to `MyTableView* would break.
(UITableView *) means the first argument is of type UITableView
tableView means that the name of the variable inside this method for the calling table view is tableView
Think about reading through the View Controller Programming Guide - it covers a lot of these concepts and links to more documents that explain delegation, table views, etc.
1.) File owner is the (generally) UIViewController subclass associated with the View you are building in IB (what you call GUI builder is actually termed Interface Builder)
First Responder is generally used in the background by the program to indicate what has control at the moment (generally don't do much with this)
The delegate is the file that receives the actions done on the view (and thus must implement how to handle these), (see below)
2.) Generally you will have a ViewController code file for each Interface Builder View (the File Owner). Generally this will be where the actions are handled for specific components (say, clicking on a button). You will set up variables (and methods for button clicks and etc) to handle each component from IB (a textfield or button is an IBOutlet, while an action like clicking on a button is an IBAction) As far as best design, I believe you should have a delegate for each view that does all the above, but I generally just use the ViewController as the delegate and implement it there (for relatively simple views)
3.) No, the parameter name (which is what tableView and MyTableView are in your examples) are used inside the function to indicate the value that you passed it. When you call this function you would call it like [myTableView numberOfRowsInSection:2]; and inside the function anything you needed from "myTableView" is actually referenced by the parameter name tableView...That is for any function, but for UITableViewDelegate methods (like the one you are referencing, it will be called automatically by the UITableViewController if it's delegate is set to the file you define this function.
Wow looking back thats some blocks of text, my best advice would be to get Beginning iPhone Development by Mark and LaMarche, it addresses all this very well.
I'd also suggest looking at some of the very basic examples in the Apple documentation to get a gist for how Interface Builder and delegates are properly used.
Edit: as a commenter pointed out, the Stanford iOS course is fantastic and where i learned the basics (along with the book above)
See my answer to this question for an explanation of what "loading a xib file" means and the meaning of File's Owner and outlets. It's perhaps a bit advanced for a beginner, but if you really want to know the "what" of what's going on and figure out the "why do it this way" for yourself, it's probably a good read:
Put a UIView into a UITableView Header

The concept of file's owner,first responder, and application delegate in iPhone [duplicate]

This question already has an answer here:
Closed 13 years ago.
Possible Duplicate:
iPhone Interface Builder and Delegates
What is the relationship between these three component in the Objective C / iPhone world? I found that the App Delegate have some relationship with the UI and the variable in code. It match the variable and related UI object on the view. But I found that the File's owner have the outlet called delegate that related to the Application delegate, what is their relationship. Also, the first responder, it seems it just receive some effect only. What's going on between there stuff?
One at a time:
File's Owner: This is the object that loads the xib file. In a completely generic sense, this is the object passed as the owner parameter to -[NSBundle loadNibNamed:owner:]. When working with a nib for a UIViewController subclass, this is usually the UIViewController subclass itself. Further reading: Resource Programming Guide: Nib Files
First Responder: This is the view that receives untargeted events (i.e. those sent with a target of nil) first. The useful part of this is that it's connected to the idea of the responder chain, which is a mechanism by which things higher up in the view hierarchy can capture unhandled and deal with them. This concept originated on the Mac, and is particularly useful for implementing something like the "Copy" menu item. The first responder is the target of the "Copy" menu item, meaning that the selected text field gets a chance to handle the copy event first, then its superview, and so on. Further reading: iPhone Application Programming Guide: Event Handling
Application Delegate: This is simply the delegate of the application's UIApplication object. It typically receives general status messages about the application, such as when it starts, ends and what not. It's a good spot to kick off things that need to happen when your app starts or shuts down. Further reading: Cocoa Fundamentals Guide: Delegates and Data Sources
Hope that helps.

Where can I find a list of pushViewController transitions?

Where can I find a list of transitions for bringing a new Viewcontroller onto the stack.
My line of code is:
[peoplePicker pushViewController:myDetail transition:6];
after selecting a contact. Where can I find a list of transitions, and why does "6" work correctly?
Also I get a warning with this code saying it may not respond to transition, even though it produces the transition correctly. What is the proper way to do these animations?
Thanks,
That method is a private method that isn't intended to be used by 3rd party developers.
The reason it works is because of Objective-C's dynamic design. While Apple can hide their methods in private categories, they can't prevent them from being called during runtime.
I assume you're getting a warning explaining that UINavigationController (or whatever the class is) may not respond to that method and will assume it returns (id) and takes ... as arguments. That is unless you've exposed the method yourself.
Either way, this will be caught by Apple during review and your app will very likely be rejected. Private API usage is forbidden by the terms of the SDK.
I suspect that the exciting new types of transitions might come out as soon as 3.2 gets released. Or when 4.0 gets released, whenever that is. Until that time, I think you might be stuck with pushViewController:animated:. If you're looking for other ways to make views show up, you could use a modal view controller. Check out the UIViewController documentation and you'll see presentModalViewController:animated:.

UITableViewController.view crash

So I'm trying to use a UITableViewController (let's call it homeView) in my iPhone application to display a simple table with only a few rows of text which are loaded from an NSArray in the controller. I want to display the table in the grouped style in a subview of a subview (let's call it subSubView) of my main controller. When I try the following: [subSubView addSubview:homeView.view], my app crashes on launch. However, when I allocate the object without adding it to any views, it launches fine.
What's the best way (or rather a working way) to display the table generated by my UITableViewController?
There isn't enough to tell for sure what is going on, but if I had to guess I would think that you probably aren't retaining homeView. Normally I would say that as a comment to your question, since it is not really an answer, but I have a completely separate answer:
Just use a UITableView, not a UITableViewController. Instead of trying to embed a controller within a controller (which is quite difficult since Apple doesn't expose the necessary tools to actually modify the view controller hierarchy), just make the VC you are writing support the appropriate delegate/dataSource methods and directly create the view.
While it might make some logical sense to try to embed VCs inside of each other, with the exception of the builtin container VCs (UINavigationController, UITabBarController) it Really Doesn't Work™. The technical reason for this is that internally some of the event routing and messaging depends on parentViewController being correct, but since you can't set it (setParentViewController: is private) tons of latent bugs in UIKit start rearing their head. The internal collection classes can set the parentViewController correctly, so everything works right.
Also, one last thing. In your question you named your view controller homeView. Please, please on't do that. A view controller and a view are separate things, call it homeViewController. Aside from the fact that a lot of new iPhone developers get confused about what the distinction is, there is nothing more aggravating then tracing through someone else's code and realizing that something you are assuming is one type is another.