here is my question, let s say i have UIViewController A B C D...
currently I am using the default transiation animiation for all VCs modal transite , shows as ->
what i want is... let user pick what kind of transiation animation they like to use..for all the VC modal transition animations...
i guess some code need to be added in some where here? ->
- (IBAction)cardAction:(id)sender {
UIImage *img = [(UIButton *)sender currentBackgroundImage];
[self performSegueWithIdentifier:#"cardSegue" sender:img];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"cardSegue"]) {
UIImage * img = (UIImage *)sender;
ResultViewController *viewcontroller = [segue destinationViewController];
viewcontroller.img = img;
}
}
please help..
A segue lets you define the transition in the Storyboard but you want to let the user define the transition. UIStoryboardSegue doesn't let you do this, so you're going to need to perform the transition yourself.
There's a good answer on performing transitions using different styles here:
How to change the Push and Pop animations in a navigation based app
Instead of calling performSegueWithIdentifier, you'd use the code from that answer to perform the transition.
You can just create your own segue subclass and then changing the
- (void) perform;
function.
If you need an example for the segue subclassing go to this tutorial:
>>> Link to tutorial <<<
Regards,
Nils
Related
I'm new on Stackoverflow and I'm currently learning XCode from scratch and I'm in a process of making a Single Page Application with options.
Anyone knows how to efficiently make a simple menu with multiple selectable UIButtons that make the main ViewController display different datasets depending on the selection in XCode?
Tried different things (creating SecondViewController for example but can't figure out how to pass data from it to main ViewController).
Any help will be greatly appreciated.
Refer this:
https://www.appcoda.com/storyboards-ios-tutorial-pass-data-between-view-controller-with-segue/
How to pass prepareForSegue: an object
Simple Test from above Answer Reference:
Simply grab a reference to the target view controller in prepareForSegue: method and pass any objects you need to there. Here's an example...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
[vc setMyObjectHere:object];
}
}
REVISION: You can also use performSegueWithIdentifier:sender: method to activate the transition to a new view based on a selection or button press.
For instance, consider I had two view controllers. The first contains three buttons and the second needs to know which of those buttons has been pressed before the transition. You could wire the buttons up to an IBAction in your code which uses performSegueWithIdentifier: method, like this...
//When any of my buttons are pressed, push the next view
- (IBAction)buttonPressed:(id)sender
{
[self performSegueWithIdentifier:#"MySegue" sender:sender];
}
// This will get called too before the view appears
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MySegue"]) {
// Get destination view
SecondView *vc = [segue destinationViewController];
// Get button tag number (or do whatever you need to do here, based on your object
NSInteger tagIndex = [(UIButton *)sender tag];
// Pass the information to your destination view
[vc setSelectedButton:tagIndex];
}
}
Hope this help but please go through refernces!
I have a simple app with 2 screens.
When I press a button to go from the first to the second, everything is performed successfully (including animation). However, when I click the back button on the second screen, I get the following warning:
Warning: Attempt to present <getTextViewController: 0x8f6aa30> on <SecondViewController: 0x946cc80> whose view is not in the window hierarchy!
EDIT: Please don't refer me to other questions regarding above warning - I already saw those, and they refer to other issues.
However, it still switches back to the first screen. Yet, the animation of the segue does not perform.
Also: Information (such as inputted text) in the first screen remains when I return to the first screen, while information in the second screen resets every time the screen comes up.
Here is how I call both operations:
Segue from View 1 to View 2:
Name: F21, Style: Modal, Transition: Cross Dissolve, Animation: True.
Segue from View 2 to View 1:
Name: F12, Style: Modal, Transition: Cross Dissolve, Animation: True.
Code in getTextViewController.m (View 1):
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"F21"]){
UIViewController *v = [segue destinationViewController];
[self dismissViewControllerAnimated:NO completion:nil];
v = self;
}
}
-(void)performSegue:(NSString*)str{
[self performSegueWithIdentifier:str sender:self];
}
//In some other method:
[self performSegue:#"F21"];
Code in SecondViewController.m (View 2):
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"F12"]){
UIViewController *v = [segue destinationViewController];
[self dismissViewControllerAnimated:NO completion:nil];
v = self;
}
}
-(void)performSegue:(NSString*)str{
[self performSegueWithIdentifier:str sender:self];
}
- (IBAction)goBack:(id)sender {
[self performSegue:#"F12"];
}
I would very much appreciate any help to understand why the first segue works while the second doesn't.
Thank you,
Dean
NOTE: Here is the full project - https://github.com/dean13-meet/firstIOSApp
EDIT: Updated git.
Im not exactly sure what you're trying to do in your prepareForSegue, their is no need to be dismissing VC's there. If you want to have a simple app where you go from VC1 to VC2 and then back again, your best bet is to use a segue and an unwindSegue.
So in your storyboard control drag from a button on VC1 to VC2 and select your segue type. Then in VC1.m setup the unwind segue such as:
- (IBAction)unwindFromViewController:(UIStoryboardSegue *)segue
{
//empty implementation
}
Finally, in your VC2 control drag from the back button to the green exit icon on VC2 and select your unwindFromViewController method.
That should do what you're looking for.
For the sake of simplicity, I would suggest using a push segue opposed to modal because it takes care of all the back buttons for you. If you don't like the idea of a navigation controller however, try dismissing the view with the following: Moving back from a Controller to a previous one
I have a view with an Image View, when the user clicks on it, I want to load the image inside it in a separate view.
This is my segue:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"Show Player Information"]){
if ([segue.destinationViewController isKindOfClass:[PlayerViewController class]]){
PlayerViewController *playerViewController = (PlayerViewController*)segue.destinationViewController;
[playerViewController setPlayer:[self.team.players objectAtIndex:self.tableView.indexPathForSelectedRow.row]];
}
}else if([segue.identifier isEqualToString:#"Show Image"]) {
if ([segue.destinationViewController isKindOfClass:[ImageViewerViewController class]]){
ImageViewerViewController *imageViewerViewController = (ImageViewerViewController*)segue.destinationViewController;
[imageViewerViewController setImageName:#"France.jpg"];
}
}
}
But nothing happens when clicking on the image view though the segue has the correct identifier.
Please check the below screenshot
Could you help me please?
I appreciate your time and efforts.
Regards,
Although it is possible to perform a segue from a UIImageView (although not directly from IB) in my opinion is much simpler to just replace it with a UIButton and set its image instead.
Then, based on your posted code, you could just remove your old segue, ctrl+drag from the button to your destination controller, choose 'push' and then set the segue identifier to Show Image.
It should be noted here that UIImageView (unlike its ancestor UIView) has its userInteractionEnabled property set to NO by default (more about it here). So if you choose to handle any events directly from the UIImageView make sure that you switch it to YES (here is a similar answer regarding this).
I am having issues displaying data in a tableview from a push segue. How do you make data appear in the tableview from the push segue? Do I need to implement a delegate/protocol? What method would I add my logic to display the rows in the TableViewController from the push segue. I able to navigate to the tableview and back to the button sort view controllers.
Can someone show me the process similar how I wrote My Logic? I am stuck on step 4. If you have a easier way to execute please let me know.
Controllers I am trying to coordinate.
"EventFeedController.m " TableViewController executed from Tab Bar Controller. This shows the events.
" ButtonSort.m " to push segue to EventFeedController.m
AppDelegate.m has array.
My Logic...
In the storyboard.
Control drag from UIButton in ButtonSort directly to EventsFeedViewController (not to the navigationcontroller but directly to the view EventViewController itself. ). (Not sure if I should control drag to view controller or the navigation controller of EventsfeedViewController)
Select push segue from popup of the control drag
Give Button a identifier of Button01 (This would find items array where eventFeed.eventType = #"Festival";) So for clarity Button01 = Find events with eventFeed.eventType = #"Festival";
Step I am stuck on. Not sure how to access or display the array created in AppDelegate.m didFinishLaunchingWithOptions paragraph. I thought cellForRowAtIndexPath in EventsFeedViewController would be responsible for being called and displaying the rows again.
Sample of array code AppDelegate.m
Events array created AppDelegate.m. I need to pull the event when clicking the push button segue.
_events = [NSMutableArray arrayWithCapacity:20];
//***************************************
// Event feed related area
//***************************************
SDEventsFeed *eventFeed = [[SDEventsFeed alloc] init];
eventFeed.eventTitle = #"Event Fest Test 1";
eventFeed.eventDescription = #"This is not to be missed";
eventFeed.eventStartTime = #"2:00 PM";
eventFeed.eventImage = [UIImage imageNamed:#"fest.jpg"];
eventFeed.eventType = #"Festival";
[_events addObject:eventFeed];
In the table view controller that you want to push to display the data, you will need to add a property to hold that data. Something like the following:
#property (nonatomic, strong) MyDataClass *myData;
Then in the view controller that you're pushing from (the one with the button that pushes the table view controller), you'll want to add a method - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender. You can implement it in a way like the following:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"YourSegueIdentifierFromStoryboard"]) {
YourTableViewControllerClass *viewController = segue.destinationViewController;
viewController.myData = self.myData;
}
}
To pull the data from the AppDelegate you would need to do the following.
Make sure you import the AppDelegate.h into your class doing the segue.
You can create a NSMutableArray property in AppDelegate.h to hold the array data "eventArray".
This is just one possible solution.
ButtonSort.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Button01"]) {
YourTableViewControllerClass *viewController = segue.destinationViewController;
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
viewController.events = appDelegate.eventsArray;
}
}
I was wondering how to properly use the storyboard to put up a view controller modally. Personally I prefer working with xibs, but it seems that the storyboard is gaining popularity and will be the way to go in the future.
The way I would normally put up a view controller modally would be like this: let's say we have ViewControllerA (A for short) and ViewControllerB (B for short).
I would then normally put a protocol in B.h specifying the delegate method when B wants to be dismissed and add the id<theProtocol> delegate field as an assign property. Assuming i'm busy in A and I want to present B modally, I would write:
B* b = [[B alloc] initWithNibName:#"B" bundle:nil];
b.delegate = self;
[self presentModalViewController:B animated:YES];
Using the storyboard, I know it's possible to put up a different view controller in a modal way by ctrl-dragging from a button to a viewcontroller and selecting modal as transition type. I'm just wondering though; where do I set the delegate of the new view controller? What's the correct practice of passing things to your modal view controller? I don't really know what the whole deal with Segues is...
Take a look at this tutorial
According to it, you should set the delegate as follows:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"AddPlayer"])
{
UINavigationController *navigationController =
segue.destinationViewController;
PlayerDetailsViewController
*playerDetailsViewController =
[[navigationController viewControllers]
objectAtIndex:0];
playerDetailsViewController.delegate = self;
}
}
Where #"AddPlayer" is the name of your 'modal' segue
Instead of using the navigation controller you could directly use the UIStoryboardSegue object passed in prepareForSegue. It has a property called destinationViewController which is the view controller that is being instantiated. I find that a lot cleaner.
This is an example.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"AddPlayer"])
{
PlayerDetailsViewController
*playerDetailsViewController =
(PlayerDetailsViewController *) segue.destinationViewController;
playerDetailsViewController.delegate = self;
}
}
IMO I think that storyboards are great because they function like a blueprint of your application. Also I've never liked nibs. =D