I'm used to loading ViewControllers from storyboard files or xib files, so when I first tried to load one in code:
UIStoryboard *storyboard = self.storyboard;
ProfileViewController *profViewController = [storyboard instantiateViewControllerWithIdentifier:#"ProfileView"];
NSLog(#"Self View Frame: %#", NSStringFromCGSize(self.view.frame.size));
NSLog(#"ProfViewCont Frame: %#", NSStringFromCGSize(profViewController.view.frame.size));
I got the following error:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSPlaceholderMutableString initWithString:]: nil argument'
What do I need to do differently assuming that my storyboard xib is loaded properly? Here is the viewDidLoad:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// add subviews
self.view.backgroundColor = [UIColor clearColor];
self.view.opaque = YES;
[UIView beginAnimations:nil context:nil];
[self.view setFrame:CGRectMake(0, 480, 320, 480)];
[UIView setAnimationDuration:0.75f];
[self.view setFrame:CGRectMake(0, 0, 320, 480)];
[UIView commitAnimations];
// Sort stat bars top to bottom (HP == 0):
statBars = [statBars
sortedArrayUsingComparator:^NSComparisonResult(id label1, id label2)
{
if ([label1 frame].origin.y < [label2 frame].origin.y)
return NSOrderedAscending;
else
return NSOrderedDescending;
}];
// Sort types left to right:
types = [types
sortedArrayUsingComparator:^NSComparisonResult(id label1, id label2)
{
if ([label1 frame].origin.x < [label2 frame].origin.x)
return NSOrderedAscending;
else
return NSOrderedDescending;
}];
[self displayInfo:currentIndex];
}
Thanks for your help!
Never mind, it turns out the error was in [self displayInfo:currentIndex] the last line in ViewDidLoad. I mistakenly thought that viewDidLoad was safely called when the ViewController was instantiated. It turns it is called much later, when I called self.view.
<_< lazy initialization, huh?
Check your ProfileViewController xib , you must have connected some wrong outlet to the file owner
Related
This is a Phonegap app. I am completely lost here, please help.
I followed this tutorial to the t.
Here is my MainViewController.m:
- (void)webViewDidFinishLoad:(UIWebView*)theWebView
{
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
if([UIApplication sharedApplication].statusBarOrientation ==
UIInterfaceOrientationPortrait ||
[UIApplication sharedApplication].statusBarOrientation ==
UIInterfaceOrientationPortraitUpsideDown) {
adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
}
else {
adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
}
adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
CGRect adFrame = adView.frame;
adFrame.origin.y = self.view.frame.size.height-adView.frame.size.height;
adView.frame = adFrame;
[self.view addSubview:adView];
// Black base color for background matches the native apps
theWebView.backgroundColor = [UIColor blackColor];
return [super webViewDidFinishLoad:theWebView];
}
Fast answer:
What you need to do is conform to the ADBannerViewDelegate protocol and hide the ad when it fails to receive an ad.
Step by step version:
In that method you listed, you'll want to also include adView.delegate = self.
In MainViewController.h, where it says #interface MainViewController : UIViewController, you want to add <ADBannerViewDelegate> after, like this:
#interface MainViewController : UIViewController <ADBannerViewDelegate>. If there is already something in < > there, just add a comma and add ADBannerViewDelegate.
Back in the MainViewController.m, add these methods:
- (void)bannerViewDidLoadAd:(ADBannerView *)banner {
adView.hidden = NO;
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
adView.hidden = YES;
}
I'm trying to setup a tap gesture in my code and I get a crash when I try to determine the coordinates. Any help would be appreciated.
2012-09-14 17:25:49.149 valhalla[16469:707] tap detected
2012-09-14 17:25:49.159 valhalla[16469:707] -[UITapGestureRecognizer translationInView:]: unrecognized selector sent to instance 0x37bf10
2012-09-14 17:25:49.165 valhalla[16469:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITapGestureRecognizer translationInView:]: unrecognized selector sent to instance 0x37bf10'
*** First throw call stack:
(0x3104c88f 0x3611d259 0x3104fa9b 0x3104e915 0x3104f788 0x7a4a1 0x31870637 0x31800d65 0x31a31479 0x3177cf55 0x3177baa3 0x317887e9 0x31788627 0x317881f5 0x3176e695 0x3176df3b 0x313e222b 0x31020523 0x310204c5 0x3101f313 0x30fa24a5 0x30fa236d 0x313e1439 0x3179ccd5 0x75307 0x752c8)
#import "GLViewController.h"
#import "GLView.h"
#implementation GLViewController
- (void)loadView {
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
GLView *glView = [[[GLView alloc] initWithFrame:applicationFrame] autorelease];
self.view = glView;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSingleTap:)];
singleTap.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:singleTap];
[singleTap release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// We can run in landscape mode
return (UIInterfaceOrientationIsLandscape(interfaceOrientation));
}
/*- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
//[self.view becomeFirstResponder];
//[self.view setReturnKeyType:UIReturnKeyDone];
}*/
- (void)didReceiveMemoryWarning
{
// default behavior is to release the view if it doesn't have a superview.
// remember to clean up anything outside of this view's scope, such as
// data cached in the class instance and other global data.
[super didReceiveMemoryWarning];
}
- (void) handleSingleTap: (UIPanGestureRecognizer *) uigr
{
NSLog(#"tap detected");
CGPoint translation = [uigr translationInView:self.view];
CGPoint finalPosition = self.view.center;
finalPosition.x += translation.x;
finalPosition.y += translation.y;
}
#end
Your declaring a UITapGestureRecognizer but your method is casting to a UIPanGestureRecognizer
- (void) handleSingleTap: (UIPanGestureRecognizer *) uigr
UITapGestureRecognizer does not declare translationInView. That is why your app is crashing.
You want to be using locationInView: not translationInView:
I am creating a window-based application in XCode 4 (I am using window-based because I like how the universal apps are organized), but I am having trouble with the UIImagePickerControllerSourceTypeSavedPhotosAlbum. I tried stripping down the code as much as possible to avoid any external errors, but I want to have two views:
the parent view: threeeyesmain.h / m / xib
the sub view: threeeyescamera.h / m / xib
I will post the code I have so far below.
The main issue is, when I push the button to take a picture with the camera, it works and I can see the camera controls, and I can even take a picture with no problem. However, whatever objects that are in the parent view are covering the camera screen. (i.e. if I am pointing my camera over a picture of a flower, I can see the flower on the screen, but there are buttons and imageviews from the parent view overlayed on it. I hope that makes sense).
(Side note: The funny thing is, when I tried this before using a view based application, it seemed to work, but now using virtually the same code in a windows based application, I get these problems.)
Maybe I am just missing something really obvious. Any help would greatly be appreciated. Thanks!
threeeyesmain.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <AVFoundation/AVAudioPlayer.h>
#import <MediaPlayer/MediaPlayer.h>
#interface threeeyesmain : UIViewController {
}
-(IBAction)switchtothreeeyescamera:(id)sender;
-(IBAction)back:(id)sender;
#end
threeeyesmain.m
#import "threeeyesmain.h"
#import <AVFoundation/AVAudioPlayer.h>
#import <MediaPlayer/MediaPlayer.h>
#import "threeeyescamera.h"
#implementation threeeyesmain
-(IBAction)switchtothreeeyescamera:(id)sender{
threeeyescamera *mythreeeyescamera = [[threeeyescamera alloc]
initWithNibName:#"threeeyescamera"
bundle:nil];
UIView *thecurrentView = nil;
thecurrentView = self.view;
UIView *thenextView = nil;
thenextView = mythreeeyescamera.view;
thenextView.alpha = 0.0;
[self.view addSubview:thenextView];
[UIView beginAnimations:#"fadeview" context:nil];
[UIView setAnimationDuration:0.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDelegate:thenextView];
thenextView.alpha = 1.0;
[UIView commitAnimations];
}
-(IBAction)back:(id)sender {
[UIView beginAnimations:#"flipview" context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
forView:self.view.superview cache:YES];
[self.view removeFromSuperview];
[UIView commitAnimations];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#end
threeeyescamera.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <AVFoundation/AVAudioPlayer.h>
#interface threeeyescamera : UIViewController {
UIImageView *SetPhotoImageView;
UIImagePickerController *imgPicker;
UIButton *BackButton;
}
#property (nonatomic, retain) IBOutlet UIImageView *SetPhotoImageView;
#property (nonatomic, retain) IBOutlet UIImagePickerController *imgPicker;
#property (nonatomic, retain) IBOutlet UIButton *BackButton;
-(IBAction)setImage:(id)sender;
-(IBAction)back:(id)sender;
#end
threeeyescamera.m
#import "threeeyescamera.h"
#implementation threeeyescamera
#synthesize imgPicker, SetPhotoImageView, BackButton;
-(IBAction)setImage:(id)sender{
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
// if((UIButton *) sender == ChoosePhoto) {
// picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
// } else {
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
// }
[self presentModalViewController:picker animated:YES];
}
-(IBAction)back:(id)sender {
[UIView beginAnimations:#"fadeview" context:nil];
[UIView setAnimationDuration:0.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
UIView *theView = nil;
theView = self.view;
[UIView setAnimationDelegate:theView];
theView.alpha = 0.0;
[UIView commitAnimations];
[UIView setAnimationDidStopSelector:#selector(removeFromSuperview)];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
SetPhotoImageView.image = img;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSData *ImageData = UIImageJPEGRepresentation(img, 0.9);
[prefs setObject:ImageData forKey:#"ImageSpaceMiddle"];
[prefs synchronize];
SetPhotoImageView.image = [UIImage imageWithData:ImageData];
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
}
- (void)dealloc
{
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.allowsEditing = NO;
self.imgPicker.delegate = self;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if ([prefs objectForKey:#"ImageSpaceMiddle"]) {
NSData *imgData = [prefs objectForKey:#"ImageSpaceMiddle"];
SetPhotoImageView.image = [UIImage imageWithData: imgData];
}
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#end
[self.view bringSubviewToFront:viewname];
i've a problem. Serius problem. -.-'' I've an app ViewBased, with MainView and FlipsideView. When i tap on the info button the FlipsideView will appears. But when i tap Done button, sometimes, the app terminates with “EXC_BAD_ACCESS” and i don't know what i have to do!!! In the Flipside view i've also an iAd banner, managed by this code
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
[textView setFont:[UIFont fontWithName:#"TrebuchetMS" size:12]];
adView=[[ADBannerView alloc] initWithFrame:CGRectMake(0.0f, 460.0f, 0.0f, 0.0f)];
adView.currentContentSizeIdentifier=ADBannerContentSizeIdentifierPortrait;
[self.view addSubview:adView];
self.adView.delegate=self;
self.bannerIsVisible=NO;
UIDevice *theDevice=[UIDevice currentDevice];
NSString *iOS;
iOS=theDevice.systemVersion;
float iOS2 = [iOS floatValue];
if (iOS2>=4.0) {
self.bannerIsVisible = NO;
}
[super viewDidLoad];
}
-(void)bannerViewDidLoadAd:(ADBannerView *)banner {
if(!self.bannerIsVisible) {
[UIView beginAnimations:#"animateAdBannerOn" context:NULL];
banner.frame=CGRectOffset(banner.frame, 0, -50.0f);
[UIView commitAnimations];
self.bannerIsVisible=YES;
}
}
There's something wrong?
Don't call [super viewDidLoad]; twice.
set the environment variable NSZombieEnabled = YES and the run the code again. Then watch your crash logs. You are trying to access an already deallocated instance.
I am programmatically adding a UIImageView and a UILabel to multiple screens in a program I'm working on. As such, I've written a UIViewController that contains the code to load up the UIImageView and UILabel in viewDidLoad, along with a timer to update the contents. I use this view controller as a superclass for any views that need the UIImageView and UILabel.
For the most part it works fine, but when transitioning from specific screens the pair seem to start with a frame of (0,0,0,0) and slowly animate to the frame I've defined. I have no idea what the issue is or even where to look. Any pointers here would be great.
Here is the code I'm using as my superclass.
FoundationViewController.h
#import
#interface FoundationViewController : UIViewController {
IBOutlet UIImageView *activeInventoryImage;
IBOutlet UILabel *activeInventoryLabel;
NSTimer *inventoryStatusTimer;
}
#property (nonatomic, retain) IBOutlet UIImageView *activeInventoryImage;
#property (nonatomic, retain) IBOutlet UILabel *activeInventoryLabel;
- (void) advanceToView:(id)nextView;
- (void) inventoryStatus;
- (BOOL) inventoryActive:(NSDate*)inventoryExpire withImage:(NSString*)imageName;
#end
FoundationViewController.m
#import "FoundationViewController.h"
#import "GameData.h"
#import "Globals.h"
#implementation FoundationViewController
#synthesize activeInventoryImage;
#synthesize activeInventoryLabel;
- (void) viewDidLoad{
// initialize the active inventory icon and label
activeInventoryImage = [[UIImageView alloc] init];
activeInventoryLabel = [[UILabel alloc] init];
// clear
activeInventoryImage.image = [UIImage imageNamed:#""];
activeInventoryLabel.text = #"";
// set the center points
activeInventoryImage.frame = CGRectMake(258, 7, 20, 20);
activeInventoryLabel.frame = CGRectMake(280, 6, 30, 20);
// set label parameters
activeInventoryLabel.backgroundColor = [UIColor clearColor];
activeInventoryLabel.font = [UIFont fontWithName:#"Helvetica" size:11.0f];
activeInventoryLabel.textColor = [UIColor colorWithRed:0.2 green:0.4 blue:0.6 alpha:1];
// add to view
[self.view addSubview:activeInventoryImage];
[self.view addSubview:activeInventoryLabel];
// start the timer if there is any active inventory
if(
[self inventoryActive:[GameData sharedGameData].player.inventory.aExpire withImage:#"a.png"] ||
[self inventoryActive:[GameData sharedGameData].player.inventory.bExpire withImage:#"b.png"] ||
[self inventoryActive:[GameData sharedGameData].player.inventory.cExpire withImage:#"c.png"]
)
inventoryStatusTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(inventoryStatus) userInfo:nil repeats:YES];
[super viewDidLoad];
}
- (BOOL) inventoryActive:(NSDate*)inventoryExpire withImage:(NSString*)imageName{
NSTimeInterval expireSeconds;
NSDateFormatter *formatter;
BOOL runTimer = FALSE;
// expire
expireSeconds = [inventoryExpire timeIntervalSinceNow];
if(expireSeconds > 0){
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"mm:ss"];
NSDate *expireTime = [NSDate dateWithTimeIntervalSince1970:expireSeconds];
activeInventoryImage.image = [UIImage imageNamed:imageName];
activeInventoryLabel.text = [formatter stringFromDate:expireTime];
[formatter release];
runTimer = TRUE;
}
return runTimer;
}
- (void) inventoryStatus{
// if there is no active inventory kill the timer
if(
![self inventoryActive:[GameData sharedGameData].player.inventory.aExpire withImage:#"a.png"] &&
![self inventoryActive:[GameData sharedGameData].player.inventory.bExpire withImage:#"b.png"] &&
![self inventoryActive:[GameData sharedGameData].player.inventory.cExpire withImage:#"c.png"]
){
activeInventoryImage.image = [UIImage imageNamed:#""];
activeInventoryLabel.text = #"";
if(inventoryStatusTimer != nil)
[inventoryStatusTimer invalidate];
}
}
- (void) advanceToView:(id)nextView{
if([nextView isKindOfClass:[UIView class]]){
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.7];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self.view cache:YES];
[self.view addSubview:nextView];
[UIView commitAnimations];
}
else
NSLog(#" Error Loading View: %#",nextView);
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[activeInventoryImage removeFromSuperview];
[activeInventoryImage release];
[activeInventoryLabel release];
[super dealloc];
}
#end
Put a break point in advanceToView as this seems to be your only animation code. Everytime it gets called, look at the call stack in the debugger. From here, you can see what is calling this code when they are not supposed to be.
After some experimenting I've discovered using initWithFrame corrects the drifting problem.
activeInventoryImage = [[UIImageView alloc] initWithFrame:CGRectMake(258, 7, 20, 20)];
activeInventoryLabel = [[UILabel alloc] initWithFrame:CGRectMake(280, 6, 30, 20)];
I still have no idea what the root cause of the issue is. If anyone could tell me what's going on here I would love to know for future reference.