Trying to create IBAction inside custom cell with buttons inside - objective-c

I have created a my own custom cell in a nib file and I am receiving an error I don't understand.
[self presentViewController:_myMail animated:YES completion:nil];
In this line I receive there error No visible #interface for "LeadCell" declares the selector presentViewController:animated:completion:
LeadCell is the name of the controller for the custom. I would like to create an action where the user clicks the button and it opens a mail composer view to send an email.
Any clarity would be appreciated.

A clean way to solve this problem would be to store the view controller with your custom cell, like this:
#interface LeadCell {
__weak UIViewController *ctrl;
}
-(id)initWithViewController:(UIViewController*)c;
...
#end
#implementation LeadCell
-(id)initWithViewController:(UIViewController*)c {
if (self = [super init]) {
ctlr = c;
}
return self;
}
#end
When you create new cells in your "cell for row at index path", pass the view controller to the initializer of the cell. This way, the cell would be able to "find" the controller, letting you code your action by using ctrl instead of self:
[ctrl presentViewController:_myMail animated:YES completion:nil];

Because you are trying to present a view controller from subclass of UITableViewCell. The UITableViewCell have no such method for presenting the view controller.
The presentViewController method is declared for ViewController and it's subclasses.
The tableViewCell is not a viewcontroller it's a view. So there is no method like presentViewController for UITableViewCell.

Related

Remove view controller from another view controller

I am very new to iPhone app development.
I am developing one example application for iPhone emulator using Objective-C++ and std CPP.
I have two views in my application, on some events from CPP code i am displaying second view using following code from the first view controller.
// Defined in .h file
secondViewScreenController *mSecondViewScreen;
// .mm file Code gets called based on event from CPP (common interface function between Objective-C++ and CPP code)
mSecondViewScreen = [[secondViewScreenController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:mSecondViewScreen animated:YES];
I am able to see second view coming on screen, but problem is that i am unable to end/remove second view controller from first view controller.
How can i remove second view controller from first view controller using second view controller's pointer or using any other method.
To remove second view i have following code in second view controller file, which gets called on button click event of second view.
// In .mm of second view controller.
- (IBAction)onEndBtnClicked:(UIButton *)sender
{
[self dismissModalViewControllerAnimated:NO];
[self.navigationController popViewControllerAnimated:YES];
}
Above code works perfectly, when i click on the seconds view's end button it removes the second view controller from the screen and navigets to first view, how can i use same code to remove second view from the first view controller.
I tied to use NSNotificationCenter to send event from first view to second view to call the function onEndBtnClicked but it is not working.
What is the proper way of doing it?
OSX version: 10.5.8 and Xcode version: 3.1.3
In the secondViewController create a protocol like:
#protocol SecondViewScreenControllerDelegate <NSObject>
- (void)secondViewScreenControllerDidPressCancelButton:(UIViewController *)viewController sender:(id)sender;
// Any other button possibilities
#end
Now you have to add a property in the secondViewController class:
#property (weak, nonatomic) id<SecondViewScreenControllerDelegate> delegate;
You sinthesize it in the secondViewController implementation:
#synthesize delegate = _delegate;
Finally all you have to do is implement the protocol in your firstViewController and set the secondViewController properly prior presenting it:
#interface firstViewController : UIViewController <SecondViewScreenControllerDelegate>
...
#implementation firstViewController
- (void)secondViewScreenControllerDidPressCancelButton:(UIViewController *)viewController sender:(id)sender
{
// Do something with the sender if needed
[viewController dismissViewControllerAnimated:YES completion:NULL];
}
Then when presenting the secondViewController from the first:
UIViewController *sec = [[SecondViewController alloc] init]; // If you don't need any nib don't call the method, use init instead
sec.delegate = self;
[self presentViewController:sec animated:YES completion:NULL];
And ready. Whenever you want to dismiss the secondViewController from the first, just call: (inside the secondViewController implementation)
[self.delegate secondViewScreenControllerDidPressCancelButton:self sender:nil]; // Use nil or any other object to send as a sender
All that happens is that you send a pointer of the secondViewController that you can use from the first. Then you can work with it without problem. No C++ needed. In Cocoa you won't need C++. Almost everything can be done with Objective-C, and it's more dynamic.
If there are only two views in your application then use
- (IBAction)onEndBtnClicked:(UIButton *)sender
{
[self dismissModalViewControllerAnimated:NO];
}
remove line below:
[self.navigationController popViewControllerAnimated:YES];
as it is you are dismissing second view then why you want to remove it from first view.

How to override the UIBarButtonItem triggered segue defined in a storyboard

I have a UIViewController in a storyboard iPhone app that I need to reuse in several places. In the storyboard, there is a UIBarButtonItem that has a triggered segue to another controller. In some cases, however, I would like to override the behavior of the button to segue to a different view controller. I'm thinking that there must be a way to either initialize the view controller with a message that specifies the target view controller, or to set some property after the controller is initialized but before it's pushed?
One challenge seems to be that segues can't be defined programmatically (based on what I've read so far), and I don't think I can have multiple segues on the same view controller in storyboard. So I may need to do something like this:
[self presentModalViewController:myNewVC animated:YES];
... rather than use a segue, but I'm not sure how to override the behavior of the button defined in storyboard to do it that way.
Any help is appreciated.
Just create an IBAction and a BOOL for some condition to pick which view controller should be instantiated.
UIViewController *viewController;
if (someCondition) {
viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"someViewID"];
}else{
viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"someOtherID"];
}
[self presentViewController:viewController animated:YES completion:nil];

pop and refresh viewcontroller

I have three viewcontroller. when I get to the third viewcontroller, I use poptorootviewcontroller to pop to my first view controller, but when I use popviewcontroller in my third viewcontroller (i want to go back to my second viewcontroller) its poping but all the info that I edit in my second viewcontroller are there, and I want the secondviewcontroller to be new (reset this viewcontroller), like this viewcontroller to be reloaded.
here is my code in the third viewcontroller:
-(IBAction)playAgain:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
how can I do it?
thanks!
In the second viewcontroller, you should write a method viewWillAppear like below,
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//set initial values here
}
This method will call when your controller is about to appear. So while third viewcontroller will get popped, this method will get called and you can reset values.

UIViewController with no Xib showing blank when using pushViewController

I have subclassed UIViewController like so:
#interface MyClass : UIViewController
I dont have a xib file for the controller, instead I would just like to use a blank UIView and I will layout elements programmatically on that. The problem arrises when I try and push this view controller.
MyClass * thing = [[ImageGallery alloc] init];
[self.navigationController pushViewController:thing animated:YES];
A new title bar is animated in, but there is no view, its see through, so I end up seeing a static background I set on my main "window/view". How should I properly subclass a UIViewController without a xib?
What you have described is correct behaviour so far.
You will want to override the -(void)loadView method, and after the [super loadView]; call, you can set your background colour and begin to place the objects in programatically, that you desire.

UIButton tapped to swap to another xib

I have a UIButton in my MainWindow.xib
When I tap the button, I want to swap the view. How do I do that?
I also want to transfer some data between the views (such as color preference and a string)
ANy sample code OR links to where I can find my answer would be very helpful.
alloc a temporary view controller, and call initWithNibName:. Then call [self presentModalViewController:(the view controller you just made) animated:YES]; (or NO). To pass data, create a method on your other view controller, add it to its .h file, and then in your .m file for the first view controller, import it and make it a class, and call [theviewcontrollermadeearlier yourmethod:argument :argument etc.]; e.g.:
MyFirstViewController.h:
#import <UIKit/UIKit.h>
#import "MySecondViewController.h"
...
#class MySecondViewController
...
MyFirstViewController.m:
...
MySecondViewController *tempVC = [[MySecondViewController alloc] initWithNibName:#"MySecondView"];
[self presentModalViewController:tempVC animated:YES];
[tempVC passDataWithString:#"a string" andColor:yellowcolor];
MySecondViewController.h:
#interface MySecondViewController : UIViewController {
...
}
- (void)passDataWithString:(NSString *)passedString andColor:(UIColor *)passedColor;
MySecondViewController.m:
...
- (void)passDataWithString:(NSString *)passedString andColor:(UIColor *)passedColor {
// Do something
}
EDIT:
To make the button trigger this, in your first view controller's header file, add IBOutlet IBAction *buttonPressed; in the #interface section, and then between } and #end add - (IBAction)buttonPressed;
Go into Interface Builder, and connect the IBAction to the button.
Then, in your first view controller's main file, add this:
- (IBAction)buttonPressed {
// The code to execute when pressed
}