i'm new to developing with xcode,and i'm following the apple's tutorial:"Second's ios app tutorial". I've add a button to my scene "Add Sighting View Controller",and i want to switch this view to another(BirdsViewController)that have a list of bird's names. in my storyboard i've create a segue between the button and BirdsViewController and also connect the button to touch up inside, but when i run the app the button doesn't appear.Can anybody help me?thank you.
here's my code(i don't have implemented any other methods):
AddSightingViewController.h
#class BirdSighting;
#interface AddSightingViewController : UITableViewController
#property (weak, nonatomic) IBOutlet UITextField *birdNameInput;
#property (weak, nonatomic) IBOutlet UITextField *locationInput;
#property (strong, nonatomic) BirdSighting *birdSighting;
#property (strong, nonatomic) UIButton *showBirds;
-(IBAction)displayBirds:(id)sender;
AddSightingViewController.m
#import "AddSightingViewController.h"
#import "BirdSighting.h"
#import "BirdsViewController.h"
#import <UIKit/UIKit.h>
#class BirdSighting;
#interface AddSightingViewController ()
#end
#implementation AddSightingViewController
#synthesize showBirds;
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
if((textField == self.birdNameInput) || (textField == self.locationInput)) {
[textField resignFirstResponder];
}
return YES;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([[segue identifier] isEqualToString:#"ReurnInput"]) {
if ([self.birdNameInput.text length] || [self.locationInput.text length])
{
BirdSighting *sighting;
NSDate *today = [NSDate date];
sighting = [[BirdSighting alloc] initWithName:self.birdNameInput.text
location:self.locationInput.text date:today];
self.birdSighting = sighting;
}
}
}
BirdsViewController *viewController;
-(IBAction)showBirds:(id)sender {
viewController =
[[BirdsViewController alloc]
initWithNibName:#"BirdsViewController" bundle:nil];
[[self navigationController] pushViewController:viewController animated:YES];
}
I dont see any allocation and adding of button as subview to the viewcontroller's view.
I think in the app like other textfields, button is also IBOutlet. Declare button as an IBOutlet and connect the outlet to the button in the interface builder file.
#property (weak, nonatomic) IBOutlet UIButton *showBirds;
Or allocate the button and add as subview to viewcontroller's view.
Related
I have two storyboards and each one has its own respective view controller but I need to change the appearance of the second storyboard based on the button pressed in the first view controller.
In the first view controller I have:
// First view controller .h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface FirstViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIButton *LevelOneButton; // tag 0
#property (strong, nonatomic) IBOutlet UIButton *LevelTwoButton; // tag 1
-(IBAction)selectLevel:(UIButton *)sender; // both buttons connected to this method
#property (assign, nonatomic) int levelSelect;
#end
then in the first .m file:
//FirstViewController.m
-(IBAction)selectLevel:(UIButton *)sender {
if (sender.tag == 0) {
_levelSelect = 0;
}
if (sender.tag == 1) {
_levelSelect = 1;
}
}
This code works fine but the problem occurs in the secondViewController that I have. When I try and access the levelSelect property in the SecondViewController I get the errors "Property 'levelSelect' not found on object of type 'FirstViewController'" or "Unexpected identifier levelSelect" or something among those lines. I've tried every single thing I could think of and every question I found on StackOverflow relating to this but none have fixed the problem. Anyone know what I'm doing wrong?
You should be setting the property on the second view controller as you're pushing or segueing.
So in your first view controller it should look something like this:
#import "ViewController.h"
#import "SecondViewController.h"
#interface ViewController ()
#property (strong, nonatomic) IBOutlet UIButton *levelOne;
#property (strong, nonatomic) IBOutlet UIButton *levelTwo;
#property (assign, nonatomic) int selectedLevel;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.levelOne.tag = 1;
self.levelTwo.tag = 2;
}
- (IBAction)selectLevel:(UIButton *)sender
{
if (sender.tag == 1) {
self.selectedLevel = 1;
} else {
self.selectedLevel = 2;
}
[self performSegueWithIdentifier:#"pushToSecond" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
SecondViewController *dest = segue.destinationViewController;
dest.levelSelect = self.selectedLevel;
}
#end
Now, when viewDidLoad gets called on the SecondViewController that property will be set and you can use it. Like so:
#import "SecondViewController.h"
#interface SecondViewController ()
#property (strong, nonatomic) IBOutlet UILabel *levelLabel;
#end
#implementation SecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.levelLabel.text = [#(self.levelSelect) stringValue];
}
#end
Quick Edit, if you're not using segues you can do the same thing by pushing manually. Would look something like:
- (IBAction)selectLevel:(UIButton *)sender
{
if (sender.tag == 1) {
self.selectedLevel = 1;
} else {
self.selectedLevel = 2;
}
SecondViewController *secondVC = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"second"];
secondVC.levelSelect = self.selectedLevel;
[self.navigationController pushViewController:secondVC animated:YES];
}
I'm building my first iOS app to try and learn iOS coding. However, I need to pass a value xAuthToken from one controller to the other. I can't seem to get it working to. I init the value in the first controller ViewController, but then I need it in SettingsController. I keep getting errors and the one it throws now is: Property 'ViewController' not found on object of type 'ViewController'
What am I doing wrong?
ViewController.h
#import <UIKit/UIKit.h>
#import "SettingsController.h"
#interface ViewController : UIViewController <UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *txtUsername;
#property (weak, nonatomic) IBOutlet UITextField *txtPassword;
- (IBAction)sigininClicked:(id)sender;
- (IBAction)backgroundTap:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic) NSString *xAuthToken;
#end
#implementation ViewController
- (IBAction)sigininClicked:(id)sender {
NSString *xAuthToken = #"0";
self.viewController = [[SettingsController alloc] init];
self.viewController.xAuthToken = xAuthToken;
[self performSegueWithIdentifier:#"login_success" sender:self];
}
SettingsController.h
#import <Foundation/Foundation.h>
#interface SettingsController : UIViewController
#end
SettingsController.m
#interface SettingsController ()
#property (weak, nonatomic) IBOutlet UITextField *myTextField;
#property (weak, nonatomic) IBOutlet UISwitch *mySwitch;
#end
#implementation SettingsController
//THIS IS WHERE I NEED XAUTHTOKEN
If you have a segue that presents your SettingsController, pass the information it needs in prepareForSegue. Don't create a new local SettingsController.
You can do something like
viewController = [self.storyboard instantiateviewcontrollerwithidentifier:#"your vc name"];
viewController.Xauthtoken = data;
// Do something else with this.
Or another way ( I don't know if it's good or bad, use it while your vc is already active ):
Use NSNotificationCenter and pass values between it.
Third way is create delegate for first Viewcontroller.
Try this in your ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic) NSString *xAuthToken;
#end
#implementation ViewController
- (IBAction)sigininClicked:(id)sender {
xAuthToken = #"Your Value Here";
[self performSegueWithIdentifier:#"login_success" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"login_success"]) {
SettingsController *destViewController = segue.destinationViewController;
destViewController.xAuthToken = xAuthToken;
}
}
And in your SettingsController.h
#import <Foundation/Foundation.h>
#interface SettingsController : UIViewController
#property (nonatomic,strong) NSString *xAuthToken;
#end
SettingsController.m
#interface SettingsController ()
#property (weak, nonatomic) IBOutlet UITextField *myTextField;
#property (weak, nonatomic) IBOutlet UISwitch *mySwitch;
#end
#implementation SettingsController
-(void)viewDidLoad{
NSLog("%#",xAuthToken);
}
I have a total of 5 text fields in a view controller. 1 of them opens the keyboard to fill in data. 2 of them open up the picker view to select the value. 1 opens up the Date Picker. And the last one segues to a Table View Controller.
The pickers and keyboard open up fine as I transition from one text field to another. If I click on the text field to segue to the table view, it opens as well. The problem occurs when I try to open the Table View if there is currently a picker or keyboard already active. The picker or keyboard from the previous selected text field shows in front of the table view. How do I hide the picker or keyboard before going to the table view?
Link to sample project http://www.filedropper.com/test_9
.h file
#import <UIKit/UIKit.h>
#interface AddAEntryViewController : UIViewController<UITextFieldDelegate,UIPickerViewDataSource,UIPickerViewDelegate>
#property (weak, nonatomic) IBOutlet UITextField *textEntryName;
#property (weak, nonatomic) IBOutlet UITextField *textEntryStatus;
#property (weak, nonatomic) IBOutlet UITextField *textEntryLocation;
#property (weak, nonatomic) IBOutlet UITextField *textEntryGender;
#property (weak, nonatomic) IBOutlet UITextField *textDOB;
#property (weak, nonatomic) IBOutlet UIPickerView *pickerAddEntryInfo;
#property (weak, nonatomic) IBOutlet UIDatePicker *datepickerAddEntryInfo;
#end
.m file
#import "AddAEntryViewController.h"
#interface AddAEntryViewController ()
#property(strong, nonatomic)NSArray *arrayEntryStatus;
#property(strong, nonatomic)NSArray *arrayEntryLocation;
#property(strong, nonatomic)NSArray *arrayEntryGender;
#end
#implementation AddAEntryViewController{
}
#synthesize textEntryName=_textEntryName;
#synthesize textEntryStatus = _textEntryStatus;
#synthesize textEntryLocation = _textEntryLocation;
#synthesize textEntryGender = _textEntryGender;
#synthesize textDOB =_textDOB;
#synthesize pickerAddEntryInfo = _pickerAddEntryInfo;
#synthesize datepickerAddEntryInfo = _datepickerAddEntryInfo;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//TOOLBAR SETUP
CGRect cgRect =[[UIScreen mainScreen] bounds];
CGSize cgSize = cgRect.size;
UIToolbar* toolbar = [[UIToolbar alloc] init];
toolbar.frame=CGRectMake(0, 0, cgSize.width, 35);
toolbar.barStyle = UIBarStyleBlackTranslucent;
//PICKER SETUP
_pickerAddEntryInfo.hidden=YES;
_arrayEntryStatus = [[NSArray alloc]initWithObjects:#"Single",
#"Married", nil];
_arrayEntryGender = [[NSMutableArray alloc] initWithObjects:#"Female",#"Male", nil];
_textEntryStatus.inputView = _pickerAddEntryInfo;
_textEntryGender.inputView = _pickerAddEntryInfo;
_textEntryStatus.inputAccessoryView=toolbar;
_textEntryGender.inputAccessoryView=toolbar;
//DATEPICKER SETUP
_datepickerAddEntryInfo.hidden=YES;
[_datepickerAddEntryInfo setMaximumDate:maxDate];
[_datepickerAddEntryInfo setMinimumDate:minDate];
[_datepickerAddEntryInfo setDate:startDate];
_textDOB.inputView = _datepickerAddEntryInfo;
_textDOB.inputAccessoryView = toolbar;
}
#pragma mark - Text Field Editing Begins
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
//Picker - these text fields open up the Picker View
if (_textEntryStatus.editing == YES || _textEntryGender.editing == YES)
{
_pickerAddEntryInfo.hidden=NO;
}
//DatePicker - this text field opens up a Date Picker
if (_textDOB.editing == YES)
{
_datepickerAddEntryInfo.hidden=NO;
}
//TableView for Entry Location - This text field will segue to a Table View Controller populated with data
if (_textEntryLocation.editing == YES)
{
[textField resignFirstResponder];
}
}
#pragma mark - Text Field Editing Ends
-(void) textFieldDidEndEditing:(UITextField *)textField
{
[textField resignFirstResponder];
}
Use prepareForSegue: to perform any actions before segueing to another view controller.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"segueToMyTableView"]) {
// send resignFirstResponder to all textFields
[textEntryName resignFirstResponder];
[textEntryStatus resignFirstResponder];
[textEntryLocation resignFirstResponder];
[textEntryGender resignFirstResponder];
[textDOB resignFirstResponder];
// and remove all pickers views from the superview
[pickerAddEntryInfo removeFromSuperview];
[datepickerAddEntryInfo removeFromSuperview];
}
}
You can assign name to your segue in Storyboard like this (don't forget to select it on scheme)
Related documentation is here.
My destination ViewController has a number of labels and images which need to be changed dependent on the specific previous ViewController. I have a segue set up which should change these but for some reason it is not, even though the segue is being called.
My initial ViewController has a button which has a segue passing to the next ViewController with the name "aName". I'm probably missing something simple but I have been following another section of my code which does the exact same thing and works! I have also tested that the segue is successfully being called with a NSLog which returns fine. All the IBOutlets are also assigned correctly.
Initial View Controller.m:
#import "dViewController.h"
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"aName"]) {
dViewController *dVC = (dViewController *)segue.destinationViewController;
dVC.TitleLabel.text = #"abc";
dVC.1Img.image = [UIImage imageNamed:#"somepath.jpg"];
dVC.2Img.image = [UIImage imageNamed:#"somepath2.jpg"];
[dVC.1Button setTitle:#"abcd" forState:UIControlStateNormal];
[dVC.1Button setTitle:#"efgh" forState:UIControlStateNormal];
}
Destination ViewController:
dViewController.h
#property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
#property (strong, nonatomic) IBOutlet UIImageView *1Img;
#property (strong, nonatomic) IBOutlet UIImageView *2Img;
#property (strong, nonatomic) IBOutlet UIButton *1Button;
#property (strong, nonatomic) IBOutlet UIButton *2Button;
Edit: From doing some more looking around I think I should be using a delegate. It seems quite complicated and not really sure where I start. But I'll have a go at looking at what's in this thread: Changing label's text in another view controller
you have to create a variable for each label you want to change and in viewDidLoad assing the variable to the label.text
for example
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"aName"]) {
dViewController *dVC = (dViewController *)segue.destinationViewController;
dVC.titleString = #"abc";
dVC.1Image = [UIImage imageNamed:#"somepath.jpg"];
dVC.2Image = [UIImage imageNamed:#"somepath2.jpg"];
dVC.1ButtonString=#"ButtonTitle";
dVC.2ButtonString=#"ButtonTitle2";
}
in DestinationController
#property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
#property (strong, nonatomic) IBOutlet UIImageView *1Img;
#property (strong, nonatomic) IBOutlet UIImageView *2Img;
#property (strong, nonatomic) IBOutlet UIButton *1Button;
#property (strong, nonatomic) IBOutlet UIButton *2Button;
#property(strong,nonatomic)NSString *2ButtonString;
#property(strong,nonatomic)UIImage*1Image;
#property(strong,nonatomic)UIImage*2Image;
#property(strong,nonatomic)NSString* titleString;
#property(strong,nonatomic)NSString *1ButtonString;
#property(strong,nonatomic)UIImageView *1Img;
#property(strong,nonatomic)UIImageView *1Img;
- (void)viewDidLoad{
self.TitleLabel.text = self.titleString;
self.1Img.image = self.1Image;
self.2Img.image = self.2Image;
[self.1Button setTitle:self.1ButtonString];
[self.2Button setTitle:self.1ButtonString];
}
hope It help you, the problem is that with
dViewController *dVC = (dViewController *)segue.destinationViewController;
you only bring the controller not the view. and the IBOutlet belongs to the view and the view is not load i hope you understand
Read about app navigation principles. From apple:
https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/NavigationControllers.html
Put parentheses around segue.destinationViewController like this:
dViewController *dVC = (dViewController *)(segue.destinationViewController);
I set UIButton myButton to hidden on viewDidLoad
In a splitviewcontroller I have it so that when I click on a tablecell, certain items unhide which works great for my textviews but my button is giving me this:
ERROR: member reference base type void is not a structure or union
Here is some snippet of code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
detailViewController.myButton.hidden= NO;
detailViewController.textView1.hidden= NO;
detailViewController.textView2.hidden= NO;
}
in the .h file there is
#property (strong, nonatomic) DetailViewController *detailViewController;
in DetailViewController is where the button and textviews are declared as
#interface DetailViewController : UIViewController <UISplitViewControllerDelegate>{
IBOutlet UIButton *myButton;
IBOutlet UITextView *textView1;
IBOutlet UITextView *textView2;
}
#property (strong, nonatomic) IBOutlet UITextView *textView1;
#property (strong, nonatomic) IBOutlet UITextView *textView2;
#property (strong, nonatomic) UIButton *myButton;
-(IBAction)myButtonPressed;
#end
IBAction myButtonPressed in the DetailViewController.m is
-(IBAction)myButtonPressed{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
RootViewController *RVC = [storyboard instantiateViewControllerWithIdentifier:#"Root"];
[UIApplication sharedApplication].delegate.window.RootViewController = RVC;
}
Anyone have any thoughts on why the button won't behave like the other two will? Is it because I gave it an IBAction??
You forget to Put IBOutlet at the first of button creation it should be
#property (strong, nonatomic) IBOutlet UIButton *myButton; OR
#property (nonatomic, weak) IBOutlet UIButton *myButton;
And give proper connection to file's owner.
Button should be a IBOutlet and please correct it and update XIB references and you should be good.
#property (nonatomic, weak) IBOutlet UIButton * myButton;
link this to UIButton is XIB if you are using one.