I am new at xcode and I am learning something new each day, I have gotten stuck. I want to create a custom button on a second Storyboard (MapTwoViewController), lets say it is a custom button that looks like a cloud and it goes from left to right.
I have created the custom button in the storyboard and I have created the IBOutlet in the GWSMapTwoViewController.h so it looks like this and is linked to the button:
#import <UIKit/UIKit.h>
#interface GWSMapTwoViewController : UIViewController
#property (nonatomic, strong) IBOutlet UIButton *cloudAnimate;
#end
So in my GWSMapTwoViewController.m in my view did load I have the following:
#import "GWSMapTwoViewController.h"
#interface GWSMapTwoViewController ()
#end
#implementation GWSMapTwoViewController
#synthesize cloudAnimate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Move UIView
cloudAnimate.center = CGPointMake(200.0, 100.0);
[UIView animateWithDuration:2.0 animations:^{ cloudAnimate.center = CGPointMake(100.0, 200.0);}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
It just doesn't want to animate, it just goes straight to the end point, if I remove the animation code then the cloud appears at 200, 100 but if I put the animate code in it just moves to 100, 200 or whatever coordinates i put in. It just doesn't animate so its either in the starting point or the end point.
Can anyone tell when what i am doing wrong?
Move your animation code in
- (void)viewDidAppear:(BOOL)animated
because viewDidLoad is called before the view is visible.
Don't forget to call super
Related
I am working on an app in Xcode, using modal segues to navigate forwards and using unwind segues to go back to the previous view and also to the home view. However, the segue is just not working when I open up the simulator, no errors are shown and I have used the same approach to unwind segue as is used in the Apple To-do list tutorial, so not sure why this isn't working.
Below is my .h file for one of the views I want to unwind from:
#import <UIKit/UIKit.h>
#interface XYZBonBonoftheDayViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIWebView *BBoD;
- (IBAction)unwindBBoD:(UIStoryboardSegue *)segue;
#end
Here is my .m file from the same view:
#import "XYZBonBonoftheDayViewController.h"
#interface XYZBonBonoftheDayViewController ()
#end
#implementation XYZBonBonoftheDayViewController
- (IBAction)unwindBBoD:(UIStoryboardSegue *)segue
{
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
If anyone could help, this would be immensely helpful! Thanks in advance :)
I have a custom object class (Ship.h and Ship.m), and I am trying to create a new Ship type object with this code:
Ship *PlayerShip = [[Ship alloc] init];
The code is currently in my First view controller.m and under
- (void)viewDidLoad{
but I have tried it in
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
as well.
I create the PlayerShip object just fine with no problems, then I log it with
NSLog(#"Player ship: %#",PlayerShip);
It logs just fine as well.
Then in another part of my code (anywhere other than the place I put it) like for example an NSTimer I try the same NSLog line and it returns
Player Ship: Null
Is the PlayerShip object being deleted for some reason?
I would appreciate any help.
Below is my shipViewController.h
#import <UIKit/UIKit.h>
#import "Ship.h"
#interface ShipViewController : UIViewController{
IBOutlet UILabel *PlayerShipLabel;
IBOutlet UIProgressView *PlayerHullBar;
IBOutlet UIProgressView *PlayerShieldBar;
IBOutlet UILabel *PlayerCreditsLabel;
IBOutlet UIImageView *PlayerShipImage;
IBOutlet UIButton *PlayerRepairBreachButton;
}
#end
Ship *PlayerShip;
And here is ShipViewController.m
#import "ShipViewController.h"
#interface ShipViewController ()
#end
#implementation ShipViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
Ship *PlayerShip = [[Ship alloc] init];
NSLog(#"Player ship: %#",PlayerShip);
}
- (IBAction)ShieldSwitch:(id)sender {
NSLog(#"Ship is %# ",PlayerShip);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
Here is my Output from the program when the app first starts:
2014-06-12 19:02:27.503 First Game[5193:60b] Created a new ship!
2014-06-12 19:02:27.504 First Game[5193:60b] Player ship: <Ship: 0x8c30f70>
And here is the output from when I press the button to verify PlayerShip:
2014-06-12 19:02:29.472 First Game[5193:60b] Ship is (null)
There are several problems.
Why do you declare Ship *PlayerShip; in your .h file after the #end statement? That makes it a global variable. Make it an instance variable like the others but putting it in the curly braces of the #interface statement.
In viewDidLoad you create a local variable with the same name as the (soon-to-be) instance variable. Don't declare a new variable. Simply assign the new object to the (soon-to-be) instance variable.
I have a view with a label in it. The lower side of this view is filled with a subview which has it’s own view controller. This subview has a button. My goal: I want to change the label by pressing the button in the subview.
I have tried the code beneath. It works fine when I let the ViewWillAppear method of the delegate call the ‘doSomeTask’ method of the SubviewController. A timer begins to count and after a few seconds, the SubviewController calls the delegates changeLabel method, and the label is changed. However, when I call the ‘doSomeTask’ method manually by pressing the button, the delegate isn’t listening. The call doesn’t reach the changeLabel method.
Probably I am doing something ridiculously stupid here. Forgive me, I’m just learning iOS programming. Thanks in advance for all the feedback.
MyViewController.h
#import <UIKit/UIKit.h>
#import "MySubViewController.h"
#interface MyViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIView *detailView;
#property (strong, nonatomic) IBOutlet UILabel *theLabel;
- (IBAction)changeLabel:(id)sender;
#end
MyViewController.m
#import "MyViewController.h"
#import "MySubViewcontroller.h"
#interface MyViewController ()
#end
#implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
MySubViewController *subVC = [[MySubViewController alloc] init];
[self addChildViewController:subVC];
[self.detailView addSubview:subVC.view];
// [subVC setDelegate:self]; (no success trying this)
[subVC didMoveToParentViewController:self];
}
-(void)viewWillAppear:(BOOL)animated
{
MySubViewController *mySubVC = [[MySubViewController alloc] init];
[mySubVC setDelegate:self];
[mySubVC doSomeTask]; // this works fine
}
// delegate method
- (void)changeLabel{
self.theLabel.text = #"Hello!";
}
MySubviewController.h
#import <UIKit/UIKit.h>
#protocol MySubViewControllerDelegate <NSObject>
#required
- (void)changeLabel;
#end
#interface MySubViewController : UIViewController
#property (nonatomic, assign) id delegate;
- (IBAction)changeButton:(id)sender;
- (void)doSomeTask;
- (void)goChangeLabel;
#end
MySubViewController.m
#import "MySubViewController.h"
#interface MySubViewController ()
#end
#implementation MySubViewController
#synthesize delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)goChangeLabel
{
[[self delegate] changeLabel];
}
- (void)doSomeTask
{
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(goChangeLabel) userInfo:nil repeats:NO];
}
- (IBAction)changeButton:(id)sender {
// [self doSomeTask]; (no succes trying this)
}
#end
Your problem is this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
MySubViewController *subVC = [[MySubViewController alloc] init];
[self addChildViewController:subVC];
[self.detailView addSubview:subVC.view];
// [subVC setDelegate:self]; (no success trying this)
[subVC didMoveToParentViewController:self];
}
-(void)viewWillAppear:(BOOL)animated
{
MySubViewController *mySubVC = [[MySubViewController alloc] init];
[mySubVC setDelegate:self];
[mySubVC doSomeTask]; // this works fine
}
In these 2 methods you have created 2 separate variables of type MySubViewController. You have only set the delegate on the variable created inside viewWillAppear.
These are not static classes, singletons or anything else similar. If you create a variable of one type it is in no way linked to the other. The same way you can create multiple NSString's that have no bearing on each other.
Create it like so:
#implementation MyViewController
{
MySubViewController *_subVC;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_subVC = [[MySubViewController alloc] init];
}
now you can use _subVC everywhere in that file as the one reference
I'm trying to implement simgle AdBanner instance for multiple views in an iOS app. For implementing AdbannerDelegate in a viewController one has to do
bannerview.delegate= self;
where bannerview is an instance of AdBannerView. This delegate method however has to be implemented in every viewController which amounts up to a lot of repeating code. How can I make up a simple class that implements all delegate methods and then I call use them in every viewController.
I think the viewControllers you are using are subclasses of UIViewController.
And you are saying all the viewControllers have the same delegate methods.
So,what i want to do is create new ViewController class (UIDelgateViewController) by SubClassing UIViewController and add all delegate methods there , and have all the other viewControllers subclass UIDelgateViewController.
The code goes like this,
.h file->
#interface UIDelegateViewController : UIViewController<ADBannerViewDelegate>
#property ADBannerView *bannerView;
#end
.m file ->
#import "UIDelegateViewController.h"
#interface UIDelegateViewController ()
#end
#implementation UIDelegateViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_bannerView = [[ADBannerView alloc] init];
_bannerView.delegate =self;
}
-(void)bannerDelegateMethod{
}
Now your Some viewController ->
#import "UIDelegateViewController.h"
#interface SomeViewController : UIDelegateViewController
#end
#import "SomeViewController.h"
#interface SomeViewController ()
#end
#implementation SomeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view addSubview:self.bannerView];
self.bannerView.frame = ..../
}
If you want to keep always on the screen the same banner while navigating and changing views, you should consider to use View Controller containtment API
A great example is that remarkable sample code written by Apple, that shows how to keep the same banner instance while moving in a tabbar or navigation controller. It could be also a great start for you project.
I am working on a very basic app that displays a popover when the user is entering text into a UITextField. Unfortunately, the popover is not showing up and the default keyboard is appearing (which shouldn't). Here is my relevant code below:
NumberPadViewController.h
#import <UIKit/UIKit.h>
#import "NumberViewController.h"
#interface NumberPadViewController : UIViewController <UITextFieldDelegate> {
IBOutlet UITextField *numTest;
}
#property (nonatomic, strong) NumberViewController *numberPicker;
#property (nonatomic, strong) UIPopoverController *numberPickerPopover;
#end
NumberPadViewController.m
- (BOOL)textFieldShouldBeginEditing:(UITextField *) textField
{
// Create popover controller if nil
if(_numberPickerPopover == nil){ //make sure popover isn't displayed more than once in the view
_numberPickerPopover = [[UIPopoverController alloc]initWithContentViewController:_numberPicker];
}
[_numberPickerPopover presentPopoverFromRect:numTest.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
return NO;
}
My popover class is called NumberViewController.h
#interface NumberViewController : UIViewController {
}
#property (strong, nonatomic) IBOutlet UIButton *oneButton;
NumberViewController.m
#import "NumberViewController.h"
#interface NumberViewController ()
#end
#implementation NumberViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
NSInteger buttonHeight = _oneButton.frame.size.height * 4;
NSInteger buttonWidth = _oneButton.frame.size.width * 3;
self.contentSizeForViewInPopover = CGSizeMake(buttonWidth, buttonHeight);
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I have created the UITextField in Storyboard, and set the delegate there. Can anyone see what I am doing wrong?
Thanks in advance to all who reply.
Ensure the textFieldShouldBeginEditing delegate method is being called. The rest of the code looks correct.
This is just a thought, but when a popover does a popover thing i think it becomes first responder, but your text view is first responder... so it might not be able to over do it.... if this is the error then before you tell the popover to appear you can say [textView resignFirstResponder]; and see if that helps.... it's just a thought though not 100% sure i will have to do some testing ~
also check to see if _numberPicker is not nil aswell i don't know what happens if you try to display a popover with no controller but you can see if that's the problem
Seeing as your popover isn't represented in the storyboard (if I read your post right) I think you need to add the popover view as a subview in code. Something like:
[self addSubview:_numberPickerPopover];
There are potentially a few places to do this. Probably makes the most sense in your textFieldShouldBeginEditing: method, after you've inited it.