Xcode segue with an UIImageView - ios

In Xcode I can control + mouse drag from a UIButton to another UIViewController, in order to enable that button to segue to that UIViewController when a user presses the button, how can I recreate this property for UIImageView ?
I tried changing its traits to Button [Check] and User Interaction Enabled [Check], plus enabling Accessibility, and Enabling User Interaction in the Attributes Inspector, however still, nothing happens when I control + mouse drag from a UIImageView to another UIViewController.
If possible* I would appreciate a solution that doesn't involve code.
*Objective-C

Use a button.
Assign a image to the button. then make the segue

You can not add segue on UIImageView. Add segue from your UIImageView's view controller to your destination view controller. Give tap gesture to your UIImageView, in action method of tap gesture use perform segue method.
See below code
-(void)tapHandeler:(UITapGestureRecognizer*)guesture
{
[self performSegueWithIdentifier:#"YOUR SEGUE IDENTIFIER" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"YOUR SEGUE IDENTIFIER"]) {
// If you want to do any preprocessing, do here
}
}

Related

IBAction not getting fired

I have 2 view controllers in my app that user can navigate from one to another.
In my first view controller I dragged from an icon in the toolbar to the second view controller to setup a segues and selected “show” from the popup.
So far no issue, I can click on the icon in the toolbar and will take me to the second view controller without any problem.
However I have also created an action from that icon using drag and drop so now I have something like this
#IBAction func setting(sender: UIBarButtonItem) {
println("Test")
}
The problem I have is the setting action is not getting fired when I click on the toolbar icon, however it will navigate to the second view controller without a problem.
Reason I want to call the setting function is to perform something prior to moving the second view controller.
Do you see any problem with the way I have implemented this?
As you are using segue from your storyboard, then that segue is triggered before the button action.If you want to perform some action on your button click, then you have to manually call the segue like this
[self performSegueWithIdentifier:#"YourSegueName" sender:sender];
then instantiate your segue like this
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"YourSegueName"])
{
}
}

IOS segue is not working when clicking on an Image

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).

Give IBAction priority instead of segue

I'm using storyboard, and in my storyboard I got a button which I connected with another view controller. So when you click the button, the other view controller shows up. I connected this using an Action Segue - Push in the storyboard. I also connected the button with an IBAction property. The problem is when I click the button it first goes to the view controller that its connected to, and after that it executes the IBAction function. How can I change this order?
You cannot change that order. There are two things that you can do.
First:
Use the segue only.
Overwrite prepareForSegue: and place your code there. If there is more than one segure from that view controller then you can distinguish within prepareForSegue: which one is currently being performed. For that you should provide them with unique names/segue IDs.
Second:
Use the IBAction only.
Within the IBAction method, at its very end, call performSegueWithIdentifier:sender:. Again, for that you will have to name all your segues with unique segue IDs.
The question to ask yourself is, why are you using both? Pick one and stick with it IMO.
If you want to perform some actions when the segue happens you should implement
prepareForSegue:
Update to address comment
I actually don't know how I can do it in code, how can I load a ViewController that is on my storyboard without using the Action Segue Push?
The easiest way that I've found is in your Storyboard you can set an identifier for the view controller.
Notice Storyboard ID is set to MyViewController
Now in your IBAction method you can do the following.
UIViewController *myViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"MyViewController"];
[self presentViewController:myViewController animated:YES completion:nil];
I solved this by chaining the IBAction from my segue. I find this approach the most useful as I can have a "save" action without a segue (chain a button to the IBAction, sometimes useful), and also use a segue for dismissing the view controller when necessary.
-(IBAction)save:(id)sender
{
/* Do some Save stuff */
}
Then in my prepareForSegue:sender:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"save"])
{
[self save:sender];
}
}
Link up your non-segue buttons to the IBAction, and segue your unwind or other such buttons with an identifier as "save". Magic.

Conditional Segue navigation from UITableViewCell based on response to UIAlertView

My problem seems like a generic problem, yet can't seem to find an answer for it.
I have a situation where when the user taps on a custom UITableViewCell, I would like to display an alert and then based on the response to the alert, either stay on the same view (user selecting cancel) or display another view (if the user selects proceed). And I would like to do this using the storyboard feature & segues.
How would one go about this? Do you have to do this the old fashioned way?
#user, Just create the alertView the old fashion way; I do know of any storyboard feature to do this differently. Where storyboard can help is with the segues. You can call the segues programmatically. With you alert view cancel button you can just return (i.e. do nothing). For the other option, to display another view, you can programmatically call a segue to transition to the desired view. If you don't have the proper segue already defined for some other reason on your storyboard, just create a button out and use that to create the segue and name it. Name the segue by clicking on it in storyboard and use the attributes inspector to give it name (identifier). Then hide the button or put it out of the view. I typically put these type of button on the toolbar and use spacers to keep them out of the view. Here's some sample code:
Call the segue from the alert view delegate like this:
[self performSegueWithIdentifier: #"done" sender: self];
Also implement this method to do any necessary task to prepare for the segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"done"])
{
// [[segue destinationViewController] setManagedObjectContext:self.managedObjectContext];
// [[segue destinationViewController] setSelectedClient:selectedClient];
}
}
You can create segues directly from the startingViewController to multiple destinationViewControllers that can then be "performed" programmatically. You do not need to create any hidden buttons for them, which does seem like a hack.
OK I came up with a solution in keeping with the storyboard that I like.
Example:
My tableview has 2 sections, grouped, and cells are dynamic prototype. Section 0 contains one row/UITableViewCell & I don't want it to segue. Section 1 contains multiple cells that I want to trigger the segue & drill down into the detail.
In Storyboard:
I removed the segue linking the tableviewcell to the destination view controller.
I made a 'generic' segue linking the source view controller directly to the destination view controller.
In the attributes on the segue, I set the identifier ('EditTimePeriod') and set the type to Push (I presume Modal would work just the same).
In the source view controller:
In the prepareForSegue method I handled both the common 'AddTimePeriod' segue I control-dragged from my UIBarButtonItem (Add), along with the 'generic'(vc-->vc) 'EditTimePeriod' segue.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// handle the click of the 'Add' bar button item
if([segue.identifier isEqualToString:#"AddTimePeriod"]) {
TimePeriodViewController* tpvc = (TimePeriodViewController*)segue.destinationViewController;
tpvc.delegate = self;
// database & entity stuff for adding the new one to the mOC, etc
}
// handle the click of one of the 'editable' cells -
if([segue.identifier isEqualToString:#"EditTimePeriod"]) {
TimePeriodViewController* tpvc = (TimePeriodViewController*)segue.destinationViewController;
tpvc.delegate = self;
TimePeriod * newTP = [self.timePeriodArray objectAtIndex:self.tableView.indexPathForSelectedRow.row];
tpvc.timePeriod = newTP;
}
}
Then I implemented the tableView:didSelectRowAtIndexPath method, and put my condition in here. If the selected row was outside of section zero I called the EditTimePeriod segue manually, defining the sender as the selected tableviewcell:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(self.tableView.indexPathForSelectedRow.section!=0){
[self performSegueWithIdentifier:#"EditTimePeriod" sender:[tableView cellForRowAtIndexPath:indexPath]];
}
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
return;
}
would be nice to code the cell in section 0 so that it is not selectable in the first place!
Hope this helps though.
** and then 5 minutes later I took another look and realized I could just move the data from section 0 into the section header, which is more intuitive and wasn't being used anyway. leaving the design open for a standard segue from each tableviewcell without needing any condition/check. Was a good exercise anyway though :)

iOS - Create an Popover View using StoryBoard

Hi there, Now I'm trying to create a Pop-OverView using an Xcode
storyboard. Firstly, I have
rootViewController, UIViewController, and UITableViewController
I want the UIView to act as a page flip and the UITableView will show popOver under the navigationBar item controller.
For the UITableView, I want to make a Pop-Over under NavigationBar controller. The problem is, when I touch the Navigation item to show the UITableViewController, it shows correctly, but when I try to close the Pop-Over View, it won't close. And then, the navigation item doesn't work well. It shows multiple instances of popOverView when I touch it multiple times.
This doesn't seem to make sense to me. Can anyone help me out or tell me where to find documentation / tutorials on this?
UPDATE:
For the UIPopOverController, it seems to work well now, but it is still bugging me when I touch a Navigation Item multiple times. It will show multiple instances of PopOver. How can I handle it, so it will show only one instance?
I had the same problem and mostly found the solution here. Basically you change the action of the button each time it's pressed to either display or dismiss the popover. Here's the code I ended up with:
#interface FilterTableViewController : UITableViewController {
UIPopoverController *editPopover;
id saveEditSender;
id saveEditTarget;
SEL saveEditAction;
}
-(void)prepareForSegue:(UIStoryboardPopoverSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"EditFilterSegue"]){
// Save the edit button's info so we can restore it
saveEditAction = [sender action];
saveEditTarget = [sender target];
saveEditSender = sender;
// Change the edit button's target to us, and its action to dismiss the popover
[sender setAction:#selector(dismissPopover:)];
[sender setTarget:self];
// Save the popover controller and set ourselves as the its delegate so we can
// restore the button action when this popover is dismissed (this happens when the popover
// is dismissed by tapping outside the view, not by tapping the edit button again)
editPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
editPopover.delegate = (id <UIPopoverControllerDelegate>)self;
}
}
-(void)dismissPopover:(id)sender
{
// Restore the buttons actions before we dismiss the popover
[saveEditSender setAction:saveEditAction];
[saveEditSender setTarget:saveEditTarget];
[editPopover dismissPopoverAnimated:YES];
}
-(BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
// A tap occurred outside of the popover.
// Restore the button actions before its dismissed.
[saveEditSender setAction:saveEditAction];
[saveEditSender setTarget:saveEditTarget];
return YES;
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// Before we navigate away from this view (the back button was pressed)
// remove the edit popover (if it exists).
[self dismissPopover:saveEditSender];
}

Resources