Coding a Popover segue for a custom UIButton - iphone

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

Related

Back button doesnt work in ios 7

I'm using this code in all ViewControllers to create back button:
self.btnBack = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60, 44)];
[self.btnBack setBackgroundImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
[self.btnBack addTarget:self action:#selector(cancel:) forControlEvents:UIControlEventTouchUpInside];
-(void)cancel:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
But when I go to controller with UIWebView I need top tap 2 times to go back in ios 6.
And in ios 7 when I tap 1 time UIWebView disappeared show black screen with my navigation and on 2nd tap app crashes.
In all screen this works great maybe something special with UIWebView, I dont know.
Help please!
I push webview:
-(IBAction)doPrivacy:(id)sender
{
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
WebPageViewController *web = (WebPageViewController*)[storyBoard instantiateViewControllerWithIdentifier:#"WebPage"];
web.hidesBottomBarWhenPushed = YES;
web.urlToOpen = #"http://dfdfdf.co";
[self.navigationController pushViewController:web animated:YES];
}
I'm calling the same segue twice, you can fix this by unlinking the connection from the CELL DIRECTLY, to your segue, and having the segue connection originate at the top of the table hierarchy in IB, rather than nested inside the cell. Connect the segue from you View Controller itself, to the segue. If you have done this correct, when you select the segue, it should highlight the ENTIRE view it is coming from, not just the cell.

ios open modal from segue from a programmatically created button?

I am creating a button and added it to my toolBar like this:
UIButton *sendButtzon = [UIButton buttonWithType:UIButtonTypeRoundedRect];
sendButtzon.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[sendButtzon setTitle:#"More" forState:UIControlStateNormal];
sendButtzon.frame = CGRectMake(toolBar.bounds.size.width - 18.0f,
6.0f,
58.0f,
29.0f);
[toolBar addSubview:sendButtzon];
How can I open a new viewController (which i have a segue for named "MoreView")?
You implement the following action method:
-(void)buttonPressed:(UIButton*)sender
{
[self performSegueWithIdentifier:#"MoreView" sender:sender];
}
And link this to your button like so (add this line to the code in your question):
[sendButtzon addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
This causes a tap on the button to call the buttobPressed: method, which in turn performs the segue which you have defined in the storyboard.
For this you have to define an segue with name "MoreView" in story board.
or else you have to create UIViewControler on button click like this..
-(void)buttonPressed:(UIButton*)sender
{
UIViewController *destinationController = [[UIViewController alloc] init];
[self presentModalViewContrller:destinationController animated:YES];
}
or Create View Controller form story board.
-(void)buttonPressed:(UIButton*)sender
{
UIViewController *destinationController = [self.storyboard instantiateViewContrllerWithIdentifier:#"DestinationViewController "];
[self presentModalViewContrller:destinationController animated:YES];
}
Every UIViewController story board has property.

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];
}

how to change uinavigation controller back button action

I have a UINavigationController and I have to keep the the default back button "the back arrow style" I just want to ask if I can change the back button action without build new one and change its style
AFAIK you cannot change the action of the default back button itself but you can place a UIBarButtonItem as leftBarButtonItem there and assign your own action.
If there is a leftBarButtonItem defined then this is shown and not the default back button.
However, keep the GUI guidelines in mind when doing tricks like this.
No. If you want a custom back button, you have to create a custom UIBarButtonItem, then assign it to the appropriate property:
self.navigationItem.backBarButtonItem = myCustomBackItem;
The back button in UINavigationBar is generated automatically as soon as u Push a new UIView. In order for you to customize the Back button is to Create a new UIToolBar + a UIBarButtonItem with custom view.
Code below is the sample to use a custom UIBarButtonItem in UIToolBar.
// create button
UIButton* backButton = [UIButton buttonWithType:101]; // left-pointing shape!
[backButton addTarget:self action:#selector(backAction) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:#"Back" forState:UIControlStateNormal];
// create button item -- possible because UIButton subclasses UIView!
UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
// add to toolbar, or to a navbar (you should only have one of these!)
[toolbar setItems:[NSArray arrayWithObject:backItem]];
navItem.leftBarButtonItem = backItem;
Link below is the design of iOS buttons in PSD format for further modifications.
http://www.chrisandtennille.com/pictures/backbutton.psd
You can make custom button and can make action on it but you can not change default backButton action.....
self.navigationItem.leftBarButtonItem = getBackBtn;
The UINavigationController sends a message to it's delegate when it pushes and pops a ViewController.
You can find out when the back button gets pressed by implementing the following and adding <UINavigationControllerDelegate> in your .h file
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.navigationController.delegate = self;
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
self.navigationController.delegate = nil;
}
-(void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated{
//Test here if the View Controller being shown next is right below the current
// ViewController in the navigation stack
//
//Test by:
// 1. comparing classes, or
// 2. checking for a unique tag that you previously assigned, or
// 3. comparing against the [navigationController viewControllers][n-2]
// where n is the number of items in the array
if ([viewController isKindOfClass:NSClassFromString(#"ViewControllerClassThatGetsPushedOnBACK")){
//back button has been pressed
}
if (viewController.tag == myUniqueTagIdentifier){
//back button has been pressed
}
if ([navigationController.viewControllers[navigationController.viewControllers.count-2]==viewController]){
//back button has been pressed
}
}
Apple Docs UINavigationController Class Reference:
The root view controller is at index 0 in the array, the back view
controller is at index n-2, and the top controller is at index n-1,
where n is the number of items in the array.

UINavigationController and titleView

My application fit inside a UINavigationController.
Simply I setted up a MyUIViewController as rootViewController of navigationController and than I set up a customTitleView for the navigationItem of myViewController inside viewDidLoad.
Now when I push a newViewController I expect to see the previous customTitleView (as described by Apple NavigationController reference) but it doesn't.
What's wrong?
A little part of code below and the Apple UINavigationController Reference
"If the new top-level view controller has a custom title view, the navigation bar displays that view in place of the default title view. To specify a custom title view, set the titleView property of the view controller’s navigation item."
- (void)viewDidLoad {
[super viewDidLoad];
[self.navigationItem setTitleView:customTitleView];
}
Maybe the "default title view" means "nothing"? I interpreted it as the previous titleView.
EDIT
I'm trying a work around but I have some other issues.
The work around is:
In every ViewController that I push inside the NavigationController I setup in viewDidLoad the titleView getting it from the rootViewController
UiView *originalContainer = [[[self.navigationController.viewControllers objectAtIndex:0] navigationItem] titleView]
I create a newTitleView and I put inside the originalContainer.subviews (UIButton) cause I need the Target action from it.
All works perfectly for the first pushed controller but if I push another viewController in the stack (the second one pushed) I loose every reference to the navigationController. Every instance variables are nil.
This values are getted inside the viewDidLoad
firstViewControllerPushed.navigationController = (UINavigationController*)0x6693da0
firstViewControllerPushed.parentViewController = (UINavigationController*)0x6693da0
secondViewControllerPushedFromFirstViewControllerPushed.navigationController = 0x0
secondViewControllerPushedFromFirstViewControllerPushed.parentViewController = 0x0
It seems that the secondViewControllerPushed lives nowhere!!
How it's possible?
I double checked that I correctly push the viewController instead of present it modally
Couse this issue I'm not able to make a right setup of the newTitleView for the secondViewControllerPushed.
This is a hack in a half but I feel it gives you a bit more control in the viewController you are working in. So below is a small method I have setup and then I just call it in viewDidLoad - [self setUpNavBar];
And using [UIButton buttonWithType:101] is perfectly fine as it passed Apple Validation.
- (void) setUpNavBar
{
[self.navigationController setNavigationBarHidden: NO animated:YES];
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.title = #"Settings";
UIButton* backButton = [UIButton buttonWithType:101]; // left-pointing shape
[backButton addTarget:self action:#selector(backAction) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:#"Back" forState:UIControlStateNormal];
UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = backItem;
[backItem release];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Logout"
style:UIBarButtonItemStylePlain target:self
action:#selector(logoutAction)] autorelease];
}