Button changes label.text; no prepareForSegue - ios

Long story short. Massive app that uses a container and the notorious "empty segue". The container takes NSNotificationCenter notifications to perform segues off of a subclassed NSObject that contains the segues. This means the method "prepareForSegue" is not being used and if used, does nothing. NSNotification won't work on making the label.text value change if the view controller hasn't been placed on the stack yet, therefore I need something that will go first round. Here's the story:
View controller 1 has 2 buttons that when clicked will take you to view controller 2. View Controller 2 has a label that will change text depending upon which button you select. PrepareForSegue method cannot be used due to implementation of NSNotificationCenter and a container that is the listener.
I've tried using NSNotificationCenter, but as stated before, only works once the view controller has made it to the stack. I need the change to happen the first time. Thanks.
I have an IBAction tied to a button and that IBAction contains the NSNotification to swap my view controllers. The userinfo: takes a NSDictionary with objects and keys of the subclassed Segue (NSObject) that I created for the empty segues. The ContainerView controller has the observers in it for the notifications that will make the segues happen.

I made a set of parameters in the notification that did the segue. In the receiving view controller, a get parameter method performs an 'if' statement before anything is done to check those parameters and set the label text properly.

Related

prepareForSegue never got called even though I set the segue in storyboard

Im new to iOS development, Im trying to follow the course in Udacity.
But having trouble in performing the segue.
the prepareForSegue never got called in my second viewcontroller.
I have two viewcontroller, one is ViewController, the other is PlaySoundViewController.
and I have link those from story board to the real class in swift.
and I have drag from the first view controller to second one to generate a segue and named it as "gonext".
and I called performSegueWithIdentifier("gonext", sender:aduio);
and in the second view controller I implement the prepareForSegue, however, it never got called.... but it managed to go to the next view.
To go to the next view controller you have to perform the method
Self.performSegueWithIdentifier("gonext", sender:aduio);
The one thing that you are getting wrong is that you have to run the prepareForSegue method in the first view controller and not the second view controller to send the data.
So instead of running the prepareForSegue method in the second view controller just run it in the first.

Distinguishing the user action causing a view controller to be pushed

I'm subclassing UINavigationController and want to in order to add the ability to add previously popped view controllers back onto the stack, akin to a forward button in a web browser.
When the user presses a button, I want to add the most recently popped off view controller back onto the stack. I do this by getting the view controller at the top of my custom stack, and calling pushViewController:animated: with it.
In the case where taps on a table view cell or something to go forward a new way into the view hierarchy, I want to clear my "popped view controllers" stack. Similar to how if the user clicks on a new link in a web browser the "forward" history is cleared.
This is where my issue lies. I don't know how to differentiate between when I call pushViewController:animated: in order to restore a view controller, and when the user taps a cell to push one. In the latter case, I want to clear my stack, but in the former I don't want to.
I can't figure out what to do here. In a perfect world pushViewController:animated: would have userOptions: parameter or something on it that would allow me to distinguish between how it's being used, but unfortunately that parameter doesn't exist.
Such an issue must come up rather frequently. How would I deal with it in this case? How would I differentiate between the circumstances in which the method is being called?
If I follow you correctly one common approach to doing this is:
Your "goForward" method should call your superclass' pushViewController:animated:
Override pushViewController:animated: to call both your superclass' pushViewController:animated: and your "clearStack" method.
It seems to me that you need two different methods in your subclass. One for the case where you want to restore a view controller, and one where you want to clear the stack. Both will perform some custom logic and call pushViewController:animated: on super.

Segue transition from table view cell to another view controller works only some arbitrary times - why?

I use three view controllers and on each view controller I put UITableView and UITableViewCell. When I connected from the first view controller's table view cell to another view controller's from within storyboard and ran the simulator, the segue works as expected. However, when I connect from the second view controller's table view cell to the last view controller from within storyboard IN THE EXACTLY SAME WAY as the first one, then for some reasons the transition doesn't work.
If I define didSelectRowAtIndexPath: and within it call [self performSegueWithIdentifier:#"showDetail" sender:self]; in the second view controller's implementation file, the transition can work as expected. I don't care about whether it's storyboard segue or methods defined in my code to perform the transition, as long as the transition does work correctly.
However, I'd still like to know why such inconsistency occurs. As I said, I connected two storyboard in the exactly same way in both cases and checked out attribute inspector and connection inspector, but I don't find any differences between the two connection there.
Also, while the first view controller can perform the transition without the method being defined, when I define it then the transition doesn't work, issuing the following error message:
Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
I think I cannot use both approaches (i.e. storyboard segue and method calls) - I just wanted to know what derives the inconsistency here.
I use iOS 7 and Xcode 5.
First of all, if you use push segues, you can't make a push for the second segue if the first segue is modal (unless you embed your second VC in a navigation controller).
Second, make sure de segue identifiers are unique for each segue.
If you ctrl+drag a segue in storyboard, don't call performsegue in code, you just attempt to do the same operation twice. If the segue is in storyboard, in code you should use prepareforsegue delegate.
Another way of doing all of this is not using any segue in storyboard, then in code #didselectrowatindexpath you can instantiate your destination vc using [storyboard instantiateviewcontrolerwithidentifier...], then [self.navigationcontroller pushviewcontroller..] for a push segue or [self presentviewcontroller...] for a modal.
EDIT: Also, when you ctrl+drag, make sure you are dragging from the cell and not from the table.
Self Answer
I finally found out that the issue was not caused in storyboard - it's on the implementation code. Since I have to use UITableViewCellStyleValue1, I cannot use dequeueReusableCellWithIdentifier, and for some reasons the dequeueReusableCellWithIdentifier has to be used in order to make an automatic transition from cell to another view controller from within storyboard only. I checked out that using dequeueReusableCellWithIdentifier and disabling UITableViewCellStyleValue1 temporarily makes it successful to make the transition without didSelectRowAtIndexPath: method being defined.

About passing data between view controllers with delegate

FIRST SCENARIO:
I have two view controllers
VC1 has a button, and a label
VC2 has a button, and a text field
theres a modal segue between VC1 -> VC2
when I run this segue, we set VC1, as the delegate for VC2.
We go to VC2, fill out the text field, hit the button, and VC2 is dismissed.
some delegated method is run on VC1, and VC1.label is filled in.
question: is there any way to do this without dismissing VC2.. for example, if VC2.button just modal segues us back, or slides us back to VC1 im assuming it re initializes the viewcontroller and the label wont be changed. do you always have to dismiss the view controller
SCENARIO 2:
again, two view controllers.
this time its reversed.. so i have
VC1 with a textfield and a button
VC2 with a label and a button
soo now we fill out VC1, and we expect it to show up on VC2. But without a segue, they have no relationship. is there any way to pass data between VCs using delegation without one initial segue? Is this segue requirement to use delegation something specific to view controllers? Im assuming it is because in other cases we just instantiate objects, and use their delegate methods. but with view controllers we want to reference one that is already created, and not instantiate a second one.
note: im using story boards
1) You could do it without dismissing VC2, but it's not a good idea. You don't want to segue "back" to one, because, as you surmised, you're actually creating a new instance of VC1, and then if you segue again to VC2, you're creating a new instance of that too. You will keep piling up more and more instance of the two controllers and none will ever be deallocated.
2) Again, your instincts are correct -- you need to somehow get a reference to the instance of VC2 that your putting on screen in order to set yourself as delegate. You don't have to have a segue to do that, you could create the second controller in code and do a manual push or presentViewController, but that's functionally, the same as doing a segue.
Sorry, dont fully understand what you want .. but here is my take.
FIRST SCENARIO:
Why would you need to update the view that isnt on screen ?
Just update in viewWillAppear.
Otherwise you can have the delegate update it when you finish editing that textfield.
SCENARIO 2:
You need a link between the view controllers, use segues makes easy, set as delegate and pass along the info. Why make it harder than it needs to be
Many things have delegates, textfields etc, you are just saying this class / obj will do something for something else.
There are many youTubes about delegates, ie
http://www.youtube.com/watch?v=eNmZEXNQheE
For more info see this stack post - it covers everything you need to know
Passing Data between View Controllers

UIViewController viewDidAppear after dismiss?

I have an app that uses a storyboard. I am going from the "main view controller" to the others using standard segues, and I am dismissing the other viewControllers with dismissViewController. (note, they are mostly being displayed in form sheet).
Thing is, when it returns to the main view controller, I need to do some cleanup (clear out arrays, reload a tableview and so on). How would I go about doing this, since i cannot use viewDidLoad or viewDidAppear?
I think the best solution it is add block (for example closeActionBlock) for your presented controller and call this block when you hide controller. (How it is implement you can see in Objective-C Block Property with Xcode code completion)

Resources