passing data through segues - objective-c

I'm trying to use one web view and have three different buttons to take you to this web view. Each one will take you to a different website. I've created a new webview class and in this class I have a method to set which url it will go to.
In the original view controller I'm trying to send a different number through to this method but it says there is no known instance method.
The code is below:
method to set url
-(void)setUrlNo:(int)urlNo
{
if (urlNo == 0) {
url = #"http://www.twitter.com/ac3112";
} else if (urlNo == 1) {
url = #"http://www.facebook.com/ac3112";
} else if (urlNo == 2) {
url = #"http://www.adamcarlin.co.uk";
}
}
prepare for segue method
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Twitter"])
{
[segue.destinationViewController setUrlNo:1];
}else if ([segue.identifier isEqualToString:#"FB"]) {
[segue.destinationViewController setUrlNo:2];
} else {
[segue.destinationViewController setUrlNo:3];
}
}

segue.destinationViewController returns an object of type id. You'll need to cast it to your view controller type to send the message without warning:
[(YourViewController *)segue.destinationViewController setUrlNo:1];

to open a different website and send url through segue you could use this method based on a master view controller. You create a push segue from each table cell or button and drag to UIViewController and then put the segue value from the below in there to make sure you're getting the right site/value.
FollowViewController.h
#interface FollowViewController : UIViewController
#end
FollowViewController.m segue method
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
FollowDetailViewController *webController = [[FollowDetailViewController alloc] init];
if ([[segue identifier] isEqualToString:#"Facebook"]) { // Facebook
NSString *urlstr=#"https://www.facebook.com/";
webController = [segue destinationViewController];
webController.urlstr = urlstr;
webController.title = #"Facebook"; // this sets the title of the next page
}
else if ([[segue identifier] isEqualToString:#"Instagram"]) { // Instagram
NSString *urlstr=#"http://instagram.com/";
webController = [segue destinationViewController];
webController.urlstr = urlstr;
webController.title = #"Instagram"; // this sets the title of the next page
}
else if ([[segue identifier] isEqualToString:#"Twitter"]) { // Twitter
NSString *urlstr=#"https://twitter.com/";
webController = [segue destinationViewController];
webController.urlstr = urlstr;
webController.title = #"Twitter"; // this sets the title of the next page
}
else if ([[segue identifier] isEqualToString:#"YouTube"]) { // YouTube
NSString *urlstr=#"http://www.youtube.com/";
webController = [segue destinationViewController];
webController.urlstr = urlstr;
webController.title = #"YouTube"; // this sets the title of the next page
}
self.title = #"Follow"; // This sets the title of the back button, and the title of this page
}
FollowDetailViewController.h
#interface FollowDetailViewController : UIViewController {
NSString *urlstr;
}
#property (strong, nonatomic) IBOutlet UIWebView *WebView;
#property (strong, nonatomic) NSString *urlstr;
#end
FollowDetailViewController.m
#implementation FollowDetailViewController
#synthesize WebView;
#synthesize urlstr;
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:urlstr];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[self.WebView loadRequest:requestObj];
}
#end
good luck!

Related

Objective-C: How can i access another ViewController and change UI in it?

I'm trying to navigate to another view and change its UI.
I manage to access to the controller method "hideElements",
but all the elements are "NIL" and it doesnt change anything.
(When i access the ViewController.m regular with no navigation then the properties are not NIL)
Why is that and How can i solve it?
ViewController.m:
- (void)hideElements:(NSString *)identifier{
[_agreeButton setHidden:TRUE];
[_noThankButton setHidden:TRUE];
[self cleanButtons];
}
ViewController2.h
#import "ViewController.h"
#property (nonatomic) ViewController *myViewController;
ViewController2.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSString *identifire = [sender text];
ViewController* vc = (ViewController*)segue.destinationViewController;
[vc hideElements:identifire];
}
ScreenShot:
It seems that the problem is the view controller's view (and subviews including outlets) haven't been created by the time you are calling hideElements. So you can do a couple of things
1)
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSString *identifire = [sender text];
ViewController* vc = (ViewController*)segue.destinationViewController;
vc.view;
[vc hideElements:identifire];
}
2)
ViewController2.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSString *identifire = [sender text];
ViewController* vc = (ViewController*)segue.destinationViewController;
vc.shouldHideElements = YES;
}
ViewController.m
- (void)viewDidLoad {
if (self.shouldHideElements) {
[self hideElements];
}
}

Passing indexPath from UITableView

In my application I have oneUITableViewController (Uctovatrida0TableViewController) and two otherUIViewContoller (DetailViewController and examples).
Now I have a problem because I do not know how to identify index (from indexPath.row) in my firstUIViewController to then correctly referred to another UIViewController.
The code in my Uctovatrida0TableViewController.m (works well):
-(void) showDetailsForIndexPath:(NSIndexPath*)indexPath
{
[self.searchBar resignFirstResponder];
DetailViewController* vc = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailsViewController"];
Ucty* ucet;
if(isFiltered)
{
ucet = [_filteredTableData objectAtIndex:indexPath.row];
}
else
{
ucet = [self.alldataArray objectAtIndex:indexPath.row];
}
vc.uctyItem = ucet;
[self.navigationController pushViewController:vc animated:true];
}
Code in my class DetailViewConroller where I need indexPath from Uctovatrida0TableViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"Priklad"])
{
Priklad *vc = [segue destinationViewController];
Ucty* ucet;
//of course this does not work
ucet = [self.alldataArray objectAtIndex:NSIndexPath.row];
vc.uctyItem = ucet;
[self.navigationController pushViewController:vc animated:true];
}
}
Code in my class Priklad.m:
- (void)setDetailItem:(id)newDetailItem
{
if (self.uctyItem != newDetailItem)
{
self.uctyItem = newDetailItem;
[self configureView];
}
}
- (void)configureView
{
if (self.uctyItem ) {
self.prikladLabel.text = self.uctyItem.priklad;
self.uctykprikladu.text = self.uctyItem.uctykprikladu;
}
}
From your code, it seems DetailViewConroller has a property uctyItem. So in your DetaiViewController's prepareForSegue:sender: method, you can just call vc.uctyItem = self.uctyItem;.
Add a property to DetailViewConroller that you can set before pushing to it.
#property (assign, nonatomic) int index;
If you want to get selected cell indexPath then there is a method for that is : selectedIndexPath = [tableView indexPathForSelectedRow];

using prepareForSegue to get a tag / id from a label

I have a set of UILabel's and would like to put the id of the selected item into the tag. Like so:
UILabel *miII = [[UILabel alloc] initWithFrame:CGRectMake(530, 0, 25, 25)];
miII.tag=item.id;
I have the following where I am able to set the itemId property of the destinationViewController. The problem I am having is how do I access the tag from the UILabel? Or is there a better way to do this? I have included my experiences in comments and am not using a UITableView.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"prepareForSegue: %#", segue.identifier);
ItemDetailViewController *myVC = [segue destinationViewController];
//[myVC setItemId:12]; // <-- hard-coding this works
[myVC setItemId:sender.view.tag]; // this doesn't work
}
- (void)tapRecognized:(UIGestureRecognizer *)sender
{
NSLog(#"that tap was recognized with %d", sender.view.tag); // <-- this works
[self performSegueWithIdentifier: #"ItemSegue" sender: self];
}
thx in advance
The sol'n was fairly simple but a bit cryptic based upon other q's and a's. I did the following:
#interface ListViewController ()
{
#private
int _itemId;
}
.....
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// NSLog(#"prepareForSegue: %#", segue.identifier);
// NSLog(#"prepareForSegue: %#", sender);
ItemDetailViewController *myVC = [segue destinationViewController];
[myVC setItemId:_itemId]; // obviously need property for itemId on ItemDetailViewController
}
- (void)tapRecognized:(id)sender
{
NSLog(#"that tap was recognized with %d", [(UIGestureRecognizer *)sender view].tag);
_itemId=[(UIGestureRecognizer *)sender view].tag;
in ItemDetailiViewController.h ...
#interface ItemDetailViewController : UIViewController
#property (nonatomic) int itemId;

segue data passing returns nil

I need to pass a NSString to my other ViewController but it keeps returning nil.
//prepareForSegue is called from didSelectRowAtIndexPath
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([[segue identifier] isEqualToString:#"chat"]) {
NSString *userName = (NSString *) [toUsersArray objectAtIndex:[self.chatsTableView indexPathForSelectedRow].row];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ChatViewController *chatViewController = [storyboard instantiateViewControllerWithIdentifier:#"ChatViewController"];
//[chatViewController setChatWithUser:userName]; EVEN TRIED:
chatViewController.chatWithUser = username;
}
}
Here is where I declare the NSString:
#interface ChatViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, MessageDelegate> {
UITextField *messageField;
NSString *chatWithUser;
UITableView *chatTableView;
NSMutableArray *messagesArray;
}
#property (nonatomic,retain) IBOutlet UITextField *messageField;
#property (nonatomic,retain) NSString *chatWithUser;
#property (nonatomic,retain) IBOutlet UITableView *chatTableView;
- (IBAction) sendMessage;
#end
and here its still nil:
#synthesize chatWithUser;
- (void)viewDidLoad {
[super viewDidLoad];
//DO STUFF WITH chatWithUser; ADDED BREAKPOINT AND chatWithUser = nil;
//ALSO TRIED viewWillAppear;
}
What is the right way to pass data between these two View Controllers? My variables stay nil.
The problem is that you're instantiating a new ChatViewController, that's not the one that the segue is going to. You should get that controller from the segue's destinationViewController property.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([[segue identifier] isEqualToString:#"chat"]) {
NSString *userName = (NSString *) [toUsersArray objectAtIndex:[self.chatsTableView indexPathForSelectedRow].row];
ChatViewController *chatViewController = segue.destinationViewController;
chatViewController.chatWithUser = username;
}
}
// Get reference to the destination view controller
ChatViewController *ChatViewController = [segue destinationViewController];

iPhone: passing data between views

I'm trying to create a simple application to understand how to pass data between views. I have two views. The first one passes some strings to the second view with this method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"colorSegue"]) {
[segue.destinationViewController setFirstColor:self.favoriteColorTextField.text];
[segue.destinationViewController setSecondColor:self.secondColor];
[segue.destinationViewController setDelegate:self];
}
And the second view receives the data with this method.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.firstColor != nil && ![self.firstColor isEqualToString:#""]) {
self.favoriteColorLabel.text = [[NSString alloc] initWithFormat:#"Favorite color: %#", self.firstColor];
}
if (self.secondColor != nil && ![self.secondColor isEqualToString:#""]){
self.secondFavoriteColorLabel.text = [[NSString alloc] initWithFormat:#"Second favorite color: %#", self.secondColor];
}
}
Till now everything works fine, the second view visualizes the first string (but not the second one, because it's still empty). Then the second view passes back a string to the first one through delegation:
- (void)viewWillDisappear:(BOOL)animated
{
[self.delegate setSecondFavoriteColor:self.secondFavoriteColorTextField.text];
}
And the first view visualizes the string like this:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.secondColor != nil && ![self.secondColor isEqualToString:#""]) {
self.secondFavoriteColorLabel.text = [[NSString alloc] initWithFormat:#"Second favorite color: %#", self.secondColor];
}
}
Here everything works, the first view visualizes both strings.
But now I'm having a problem. If i try to pass again the strings to the second view, only the first one is passed correctly. The second view always receives secondColor with the nil value, even after its value has been set through delegation.
The variables firstColor and secondColor are declared and synthetized exactly in the same way. Can you please help me find the error?
I think you need to trasform segue.destinationViewController to SecondViewController class
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"colorSegue"]) {
SecondViewController *svc = [segue destinationViewController];
[svc setFirstColor:self.favoriteColorTextField.text];
[svc setSecondColor:self.secondColor];
[svc setDelegate:self];
}
OR
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"colorSegue"]) {
[(SecondViewController *)segue.destinationViewController setFirstColor:self.favoriteColorTextField.text];
[(SecondViewController *)segue.destinationViewController setSecondColor:self.secondColor];
[(SecondViewController *)segue.destinationViewController setDelegate:self];
}
If you want to pass data between more than 1 views then you have these options.
You can use a singleton
Use your AppDelegate.
Here is a good tutorial about singleton:
http://www.galloway.me.uk/tutorials/singleton-classes/
If you want to use AppDelegate to do it like this:
AppDelegate.h
#property (nonatomic, retain) NSString *something;
AppDelegate.m
#synthesize something;
FirstViewController.m
#import "AppDelegate.h";
(void) setSomething {
AppDelegate *AppDelegate = [[UIApplication sharedApplication] delegate];
AppDelegate.something = #"something";
}
SecondviewController.m
#import "AppDelegate.h";
(void) getSomething {
AppDelegate *AppDelegate = [[UIApplication sharedApplication] delegate];
label.text = AppDelegate.something;
}