how to perform a segue - iphone

I would like implement a button to show another view. I have defined the destination ViewController in Storyboard & created a segue (of type push) and gave it an identifier.
In my root view controller
some method ...
UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[btn addTarget:self action:#selector(showDetailView:) forControlEvents:UIControlEventTouchUpInside];
and
- (IBAction)showDetailView:(id)sender {
[self performSegueWithIdentifier:#"ShowDetail" sender:sender];
}
however it doesn't do anything. I hear a Segue is an object. do I need to have a reference to it / synthesize it in my root view controller class? Any tip would be appreciated. Thank you.

Edit:
Make sure your root view controller is embedded in a navigation controller. if it isn't, select your view controller in the storyboard designer and choose Editor->Embed In->Navigation Controller in the menu.
Original:
Double-check the Identifier (storyboard-code) and try setting sender to self. If that doesn't work you can create a Segue object yourself in code.

Related

Navigation Controller for the Main View Controller in a Utility application?

I have created a utility app that links by button to another xib called scene - I am trying to create a navigation control for that link. When the button is clicked to then have a 'back' button on my scene xib. I don't wish to have a navigation bar visible on the Main View Controller or the Flipside View Controller. I'm quite new to iOS and I have no idea how to do this?
Would it maybe just be better to have a button going back to menu on a custom HUD? I don't know if that can be done?
Thank you for any help in advance, and thank you for your time
you could create a custom UINavigationBar on your scene xib, and add the custom back button to it if you don't want to create NavigationController , alternate would be that you could just make your first view as NavigationController and push the Scene view over it and it will brings the back button on the child view which is scene, keep your navigationBar hidden when you are on MainViewController and show only on scene view.
For hide UINavigationBar:
[[self navigationController] setNavigationBarHidden:YES animated:YES];
And Your can crate Custom UIButton and put anywhere (As Your requirement).
and in its method, Write code for go back to UIViewController (previous UIVieController).
Such like,
UIButton *btnBack = [UIButton buttonWithType:UIButtonTypeCustom];
[btnBack addTarget:self action:#selector(goBack:) forControlEvents:UIControlEventTouchUpInside];
btnBack.frame = CGRectMake(10, 10.5, 36, 39); // change it , As your wish
[btnBack setBackgroundImage:[UIImage imageNamed:#"MMBack.png"] forState:UIControlStateNormal];
[self.view addSubview:btnBack];
// call method of UIButton
-(void)goBack:(UIButton *) Sender
{
[self.navigationController popViewControllerAnimated:YES];
}

Coding a Popover segue for a custom UIButton

I have a custom UIButton which I defined programmatically like this:
self.hard1 = [UIButton buttonWithType:UIButtonTypeCustom];
[self.hard1 setFrame:CGRectMake(884, 524, 105, 60)]; // set the x,y,width and height
UIImage *buttonImage = [UIImage imageNamed:#"green.jpg"];
self.hard1.layer.cornerRadius = 10;
self.hard1.clipsToBounds = YES;
[self.hard1 addTarget: self
action: #selector(buttonTapped:)
forControlEvents: UIControlEventTouchUpInside];
[self.hard1 setImage:buttonImage forState:UIControlStateNormal];
[self.view addSubview:self.hard1];
As a result of that, it doesn't show in the Interface Builder, it only comes on the screen when I run the app. This means I can't ctrl + drag from the UIButton to a ViewController to select a popover segue. Can I call a segue within my code? If not, are there any other options for me?
Blub's and tkanzakic's answers won't quite work, as a popover segue insists on having an anchor view in the storyboard when you create the segue. And as your button doesn't yet exist it will be tricky to get that right. You could anchor to an existing storyboard view, but then the popover arrow won't point to the right object when it pops over. You could move that existing view around in code to match the rect of your code-created button. But you might as well dispense with the segue altogether and perform the popover in code.
You will need to declare a popoverController property:
#property (nonatomic, strong) UIPopoverController* buttonPopoverController;
Then your button action can look something like this:
- (void) buttonTapped:(UIButton*) sender
{
ContentViewController* contentVC = [[ContentViewController alloc] init];
self.buttonPopoverController = [[UIPopoverController alloc]
initWithContentViewController:contentVC];
self.buttonPopoverController.delegate = self;
//only required if using delegate methods
[self.buttonPopoverController presentPopoverFromRect:sender.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
The ContentViewController is whichever view controller you are intending to segue to. If it is configured using a storyboard scene, you may want to do something like this when you create it:
UIStoryboard *storyboard = self.storyboard;
ContentViewController* contentVC =
[storyboard instantiateViewControllerWithIdentifier:#"ContentViewController"];
You can set the storyboard identifier using the Identity Inspector when you have the relevant view controller selected in the storyboard.
in the process of creation of the button you are assigning it an action associate to a method called buttonTapped:, you can perform the segue from there, something like this:
- (void)buttonTapped:(id)sender
{
[self performSegueWithIdentifier:#"theSegueIdentifier" sender:sender];
}
CTRL + drag a segue from the ViewController that contains your
Button --> ViewController you want to segue to
Secify an identifier (just some unique string) for that segue (
with the segue selected, open the righthand "Utilities" sidebar
and open it's "Attributes inspector" tab
Add [self
performSegueWithIdentifier:#"identifierStringYouSecifiedInStep2" sender:sender];
inside your - (void)buttonTapped:(id)sender method ! )

iOS4 - custom uiview accessing UINavigation stack

Bit confused with this one so bear with me...
I have a Navigation-based project which is working fine. I'm trying to create my first custom UIView to make a couple of buttons which I will use in multiple places. One of the buttons needs to push a viewcontroller into the navigation when it's clicked but I'm not sure how to do this.
When I had the button set up within a view controller I was using:
LocationViewController *controller = [[LocationViewController alloc] initWithNibName:#"LocationViewController" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
[controller release];
but the self.navigation controller won't work now, will it? How do I access the navigation controller of the viewcontroller that this uiview will be added to?
Hope at least some of that makes sense, as I said it's my first go at subclassing the uiview and adding it to multiple pages so I'm a bit lost.
EDIT TO ADD - I have the button click events inside the custom UIView, so that is where I'm trying to change the viewcontroller from. Should I instead wire up the events in whichever viewcontroller I add the view to?
Usually your appDelegate has a UINavigationController property. You can access it in your custom view like this:
UINavigationController *navController = (MyAppDelegate *)[[[UIApplication sharedApplication]
delegate] navigationController];
But more effective way is to make delegate method for your custom view and handle button action in your viewController.
MyCustomView.h
#protocol MyCustomViewDelegate
#interface MyCustomView : UIView {
id<MyCustomViewDelegate> cvDelegate; }
#property(nonatomic, assign) id<MyCustomViewDelegate> cvDelegate;
#protocol MyCustomViewDelegate #optional
-(void)didClickInCustomView:(MyCustomViewDelegate*)view withData:(NSObject*)data;
#end
MyCustomView.m
- (void)myButtonClick:(id)sender
{
[self.cvDelegate didClickInCustomView:self withData:someData];
}
So now you can handle this event in any place where is your custom
view.
Add the button from the interface builder or from the view controller's viewDidLoad using code:
CGRect frame = CGRectMake(0, 0, 24, 24);
UIButton *button = [[UIButton alloc] initWithFrame:frame];
[button addTarget:self action:#selector(handleMyButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
Then implement -(void)handleMyButton:(id)sender {}; in your view controller. Or you could instead write -(IBAction)handleMyButton:(id)sender {}; and link method and button using the interface builder.
Then inside the method just paste the block of code you posted above. If you started with the Xcode navigation controller template project it should work.
I think it's cleaner to hide the designated initializer initWithNibName: because it is an implementation detail.
When you say you are subclassing the UIView I don't know exactly what you mean. If you want to add another view controller with a custom view just use the UIViewController template and customize the XIB file, no need to subclass an UIView unless you are really modifying its behaviour, which I guess you are not. The view is a view, and the controller stuff like handling buttons should be in the controller.
The actual controller need to be in the navigation controller stack to be able to push another controller.
Or you can make a new navigation controller instance and push your LocationViewController.

Accessing Button Created in Subclassed UITabBarController

Ok, so I'm a little stuck and maybe someone can lend some advice.
I've subclassed UITabBarController, and am creating a custom button that overlays the tab bar whenever viewDidLoad gets called inside the CustomTabBarController.
This works great, except its not tied to any action.
What I would like to do is to have a UIModalViewController be displayed when that button is pressed. Now, preferably I would rather not make this call from the subclassed CustomTabBarController, but rather from within one of my viewControllers (rootViewController per-say) that is associated with a tab.
Can someone direct me in how to make this happen? IE, How to instantiate a button in one class and make that button respond to an action within another class.
Should I use NSNotificationCenter, delegate responders, something else? An example would be great :)
There are several approaches to achieve what you're asking for. The approach I usually take is that I do something like this:
// CustomTabBarController.h
#protocol CustomTabBarControllerDelegate
- (void)buttonAction:(id)sender;
#end
#interface CustomTabBarController : UITabBarController {
id<CustomTabBarControllerDelegate> customDelegate;
}
#property(nonatomic, assign) id<CustomTabBarControllerDelegate> customDelegate;
#end
// CustomTabBarController.m
#interface CustomTabBarController ()
- (void)buttonAction:(id)sender;
#end
#implementation CustomTabBarController
#synthesize customDelegate;
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
// Configuration of button with title and style is left out
[button addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)buttonAction:(id)sender {
[self.customDelegate buttonAction:sender];
}
#end
I don't know what you're button will be doing, so I just call the method buttonAction:. Since UITabBarController already has a property named delegate I called our delegate customDelegate. All you need to do to make the above work is to add the following line to your root view controller (or whatever controller you want to handle the button action).
customTabBar.customDelegate = self;
Of course you also have to implement the protocol.
One could also imagine not using a delegate and just set the target like this:
[button addTarget:self.rootViewController action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
The above code assumes that customTabBarController has a rootViewController property and that it has been set. Also it assumes that the root view controller has the following method:
- (void)buttonAction:(id)sender;
I prefer the delegate approach as it is the more general approach, but the later approach will also work. Using NSNotificationCenter is also an option, but I'm personally not a fan of sending notifications when it isn't necessary. I usually only use notifications when multiple objects need to respond to an event.
You can reference all the view controller in your UITabBarController with the viewControllers array. You can easily get view controller for the currently selected view with selectedViewController.
With that in mind, your CustomTabBarController action can call a methods on these view controllers. Just add method to the appropriate view controller(s) to display your UIModalViewController.

Removing a UIView

So I have a view controller called MainViewController with a button which when I press this code is called:
NewViewController *newViewController;
newViewController = [[NewViewController alloc] initWithNibName:#"NewView" bundle:nil];
[self.navigationController.view addSubview:newViewController.view];
[newViewController release];
This brings in the new view which works great. However, how can I remove this view from a button within it? In an application I wrote a while ago I simply created a method in MainViewController called RemoveView and within the XIB file for NewViewController I selected FirstResponder and then RemoveView for the button. This works but I can not replicate it in my new project and don't really understand how it works anyway!
It's not the remove view code I'm looking for, more the way of getting the method to call from another class.
If anyone could help me that would be great! :)
Thanks
Drawing the line in Interface Builder does the same thing as calling
[theButton addTarget:theController action:#selector(theAction) forControlEvents:UIControlEventTouchUpInside];
theAction needs to be a method that is defined with a type of IBAction.
For your situation, in your NewViewController.h, declare
- (IBAction)removeView;
Then in NewViewController.m:
- (void)removeView
{
[self.view removeFromSuperview];
}
In your newView.xib file, you should be able to drag a line from the UIButton that you've drawn to your File's Owner, and select the removeView action.