ios open modal from segue from a programmatically created button? - iphone

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.

Related

UIButtons not working on programmatically created UIView

I have a UIViewController which I want to display a UIView that renders as a menu. This menu will have several buttons on it. I wanted to reuse this menu a few different places in my app so I figured I would create a class called ViewFactory that has a method that returns a UIView with these buttons.
On my ViewController I call this method and get the returned UIView and add it as a subview.
This works just fine. I can see the view and all its buttons, however, the buttons do not respond to any touch events. Not sure why this is the case and curious to know what I am doing wrong.
Here is my code for the ViewFactoryClass:
- (UIView *) addCloseRow
{
// UIView container for everything else.
UIView *navRow = [[UIView alloc] initWithFrame:CGRectMake(0,225,350,45)];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.userInteractionEnabled = YES;
[navRow addSubview:button];
[button addTarget:self action:#selector(closeButtonTouchDownEvent) forControlEvents: UIControlEventTouchDown];
navRow.userInteractionEnabled = YES;
return navRow;
}
In my main NavigationController class here is how I am calling and getting the UIView:
ViewFactory *factory = [[ViewFactory alloc] init];
[self.navigationController.navigationBar addSubview:[factory MainNavigationUIView]];
Again, the UIView shows up but the buttons never respond to anything.
You added the button with target and selector for ViewFactoryClass
And now you are creating instance and trying to call an action from ViewFactory class.
You can change the method to something like this:
- (UIView *) addCloseRow : (id)object {
...
[button addTarget:[object class] action:#selector(closeButtonTouchDownEvent) forControlEvents: UIControlEventTouchDown];
...
}

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

UINavigationController subclass with custom back button

I know I can set custom back button from the view controller itself, something like:
- (void)setBackButton
{
UINavigationBar* navBar = self.navigationController.navigationBar;
UIButton* backButton = [navBar backButtonWith:[UIImage imageNamed:#"navigationBarBackButton.png"]
highlight:nil
leftCapWidth:14.0];
[backButton addTarget:self action:#selector(backButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:backButton] autorelease];
}
- (void)backButtonTapped:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
The problem is that I need to do it for all my view controllers...
One solution is to put this code in some BasicViewController and all my view controllers will subclass it.
But my question is can I subclass the UINavigationCotroller itself and set it's nab bar left button to this custom button?
The right way to do this is using UIAppearance
It provides methods on UIBarButtonItem such as
- (void)setBackButtonBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics
and
- (void)setBackButtonBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics
No. It would be better to have a custom UIViewController that handles this behavior.

pushViewController from another class

I want to push a view controller from my FirstViewController to load BookDetailsViewController. here's the setup I currently have.
// FirstViewController:(this is inside a uinavigationcontroller)
-(IBAction)viewBookDetails:(id)sender
{
NSLog(#"woo");
BookDetailsViewController *bdvc = [[BookDetailsViewController alloc] init];
[self.navigationController pushViewController:bdvc animated:YES];
}
==============================================================
// BookScrollViewController: (where the button is located)
[book1UIButton addTarget:self action:#selector(viewBookDetails:)
forControlEvents:UIControlEventTouchUpInside];
-(void)viewBookDetails:(id) sender
{
FirstViewController *fvc = [[FirstViewController alloc] init];
[fvc viewBookDetails:sender];
}
==============================================================
//how BookScrollViewController is created
BookScrollViewController *controller = [bookViewControllersArray
objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
NSString *bookTitle = #"ngee";
controller = [[BookScrollViewController alloc]initWithBook:bookTitle
imageNamesArray:imgDataArray pageNumber:page totalResult:[newReleasesArray
count]];
[bookViewControllersArray replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// add the controller's view to the scroll view
if (nil == controller.view.superview) {
CGRect frame = bookScroll.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[bookScroll addSubview:controller.view];
}
when I tap the button in BookScrollViewController it calls the IBAction I have in FirstViewController coz it prints my nslog but it's not loading pushing the BookDetailsViewController to the navigation stack.
I tried assigning a button from FirstViewController to call the IBAction and it loads just fine. So, how can I successfully call the IBAction from FirstViewController using the button from BookScrollViewController?
thanks!
When you are assigning an action in the following way:
[book1UIButton addTarget:self action:#selector(viewBookDetails:) forControlEvents:UIControlEventTouchUpInside];
You say that (current object: self) BookScrollViewController *self will respond to events UIControlEventTouchUpInside of book1UIButton. That means when user tap on button method viewBookDetails of object of class BookScrollViewController will be called.
As you mentioned in your question you have defined and implemented such method in FirstViewController.
Now you should
implement that method in BookScrollViewController that will push new controller onto navigation stack, or
set another object that will respond on that button event, that object can be of class FirstViewController, for example, [book1UIButton addTarget:self.firstViewController action:#selector(viewBookDetails:) forControlEvents:UIControlEventTouchUpInside];
When you do this:
FirstViewController *fvc = [[FirstViewController alloc] init];
you obviously create a new instance of FirstViewController. That new instance is not in a UINavigationController, so you can't push a new viewController onto its navigationController property.
What you probably want to do is reference the existing instance of FirstViewController and call the method on it instead of creating a new instance of it.

Different views for different buttons iPhone

I am a newbie in iPhone app development.
I want to develop a iPhone app as when the app is launched there are two buttons displayed for the user.
Button 1 is for User Login .
Button 2 is for User Registration .
How to add view to each of the button, where if Login button is pressed then that view is loaded with few textfields and a button to login in whereas if Registration button is pressed then the registration view is loaded with few textfields and a button to confirm registration.
There are few tutorilas of multiple views but they have only one button on one view and pressing that button the next view is loaded with one button to load the next view and so on and so forth. In my case I want many buttons (atleast 2 at the moment) on one view while app is loaded and then depending upon the button pressed that view is loaded.
Any sample code or tutorial link will be much appreciated.
Thanks in advance.
make one method and registered button event to this method
[button1 addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
[button2 addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
for e.g:
-(IBAction)buttonClicked : (id)sender
{
UIButton * btn = (UIButton *)sender;
if (btn == button1) {
LoginViewController * controller = [[LoginViewController alloc] initWithNibName:# "LoginViewController" bundle:nil];
[self.navigationController pushViewController : controller animated : YES];
[controller release];
} else if (btn == button2) {
RegisterViewController * controller = [[RegisterViewController alloc] initWithNibName:# "RegisterViewController" bundle:nil];
[self.navigationController pushViewController : controller animated : YES];
[controller release];
}
}
you want to make the views in interface builder, then on button one, you will use code like
ViewControllerSubClass1 *viewController1=[[ViewControllerSubClass1 alloc] initWithNibName:#"nibname1" bundle:nil];
[self.navigationController pushViewController:viewController1];
[viewController1 release];
for button two you would use
ViewControllerSubClass2 *viewController2=[[ViewControllerSubClass2 alloc] initWithNibName:#"nibname2" bundle:nil];
[self.navigationController pushViewController:viewController2];
[viewController2 release];