Why won't this simple view switching project work? - xcode

I'm in the process of learning how to write apps in Xcode. I'm using a book to guide me. Unfortunately the book is written with guides to Xcode 3 and I'm using Xcode 4.
Now so far there haven't been any problems, but this project doesn't work, and I simply don't get it, because it seems to make pretty good sense.
The project's goal is to use a view controller to switch between three views.
Could anyone please take a look and see what I did wrong?
Here is the entire project: http://www.2shared.com/file/CKO6ACzg/MultipleViews.html
PS: I know that as it is now the views will be stacked on top off each other and that the view isn't being cleared when you click a new button.

MultipleViewsViewController.h should be:
#import <UIKit/UIKit.h>
#class FirstViewController;
#class SecondViewController;
#class ThirdViewController;
#interface MultipleViewsViewController : UIViewController {
IBOutlet FirstViewController *firstViewController;
IBOutlet SecondViewController *secondViewController;
IBOutlet ThirdViewController *thirdViewController;
}
//#property (nonatomic, retain) FirstViewController *firstViewController;
//#property (nonatomic, retain) SecondViewController *secondViewController;
//#property (nonatomic, retain) ThirdViewController *thirdViewController;
-(IBAction)loadFirstView:(id)sender;
-(IBAction)loadSecondView:(id)sender;
-(IBAction)loadThirdView:(id)sender;
#end
MultipleViewsViewController.m should be:
#import "MultipleViewsViewController.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#import "ThirdViewController.h"
#implementation MultipleViewsViewController
//#synthesize firstViewController;
//#synthesize secondViewController;
//#synthesize thirdViewController;
-(IBAction)loadFirstView:(id)sender{
[secondViewController.view removeFromSuperview];
[thirdViewController.view removeFromSuperview];
[self.view insertSubview:firstViewController.view atIndex:0];
}
-(IBAction)loadSecondView:(id)sender{
[firstViewController.view removeFromSuperview];
[thirdViewController.view removeFromSuperview];
[self.view insertSubview:secondViewController.view atIndex:0];
}
-(IBAction)loadThirdView:(id)sender{
[firstViewController.view removeFromSuperview];
[secondViewController.view removeFromSuperview];
[self.view insertSubview:thirdViewController.view atIndex:0];
}
-(void)dealloc{
[firstViewController release];
[secondViewController release];
[thirdViewController release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
firstViewController = [[FirstViewController alloc] init];
secondViewController = [[SecondViewController alloc] init];
thirdViewController = [[ThirdViewController alloc] init];
[self loadFirstView:nil];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
Connect your buttons (which you haven't done in your project, which also might be the issue) and you're done.

Related

Load UIView defined in XIB into UIView

following a post presented here, I tried to load a view defined in a XIB file into a view, currently being displayed. Basically, what I want to do is to replace the middle view (see screenshot below) with a different view when the user clicks on the button.
This is the simple view I want to load into the middle view:
And this is the source code of the ViewController:
ViewController.h
#import
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIButton *loadxibButton;
#property (strong, nonatomic) IBOutlet UIView *middleView;
- (IBAction)buttonClicked:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (IBAction)buttonClicked:(id)sender {
NSLog(#"click...");
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"NewMiddleContent" owner:self options:nil];
UIView *nibView = [nibObjects objectAtIndex:0];
self.middleView= nibView;
}
#end
When I click on the button, nothing happens, i.e. the new view will not be displayed. Can anybody please help?
Thanks a lot
Christian
Phillip, thanks a lot!
Instead of
- (IBAction)buttonClicked:(id)sender {
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"NewMiddleContent" owner:self options:nil];
UIView *nibView = [nibObjects objectAtIndex:0];
self.middleView= nibView;
}
I now use this code:
- (IBAction)buttonClicked:(id)sender {
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"NewMiddleContent" owner:self options:nil];
UIView *nibView = [nibObjects objectAtIndex:0];
nibView.frame = CGRectMake(261, 0, 532, 748);
[[[self view] viewWithTag:2] removeFromSuperview];
[[self view] addSubview:nibView];
}
Is this want you meant, i.e. is this like "best practice"?
Bye
Christian
Your view controller has a view property which, presumably, has three subviews (left, middle, and right). Instead of just setting a middleView property in your controller, your strategy should be to update the primary view's subviews array (removing the one that's to be replaced and inserting the new one).

Save UIImageView When Unload A View - Xcode 4.5.1

Creating an app on Xcode 4.5.1 and wondering how do i save the current image in the specified UIImageView when i navigate to a different view. Then when i return to the View it loads up the saved image into the UIImageView?
Thank a lot, appreciate it :D
The code I've posted below involves passing a uiimage to a second view controller. It also includes a button on each controller to move back and forth between the two. The saved image will stay in the uiimageview when you switch to and from the views.
SecondView.h
#import <UIKit/UIKit.h>
#interface SecondView : UIViewController {
IBOutlet UIImageView *yourphotoview;
UIImage *yourimage;
}
#property (retain, nonatomic) UIImage *yourimage;
- (IBAction)back;
#end
SecondView.m
#import "ViewController.h"
#import "SecondView.h"
#interface SecondView ()
#end
#implementation SecondView
#synthesize yourimage;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
yourphotoview.image = image;
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)back {
[self dismissViewControllerAnimated:YES completion:NULL];
}
- (void)dealloc {
[image release];
[super dealloc];
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#import "SecondView.h"
#interface ViewController : UIViewController
{
IBOutlet UISlider *compression;
IBOutlet UISwitch *smurferderp;
SecondView *SecondViewdata;
}
#property (retain, nonatomic) SecondView *SecondViewdata;
#property (retain, nonatomic) IBOutlet UIImageView *theimage;
- (IBAction)switchview:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#import "SecondView.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize SecondViewdata, theimage;
- (IBAction)switchview:(id)sender {
SecondView *secondview = [self.storyboard instantiateViewControllerWithIdentifier:#"rr"];
self.SecondViewdata = secondview;
SecondViewdata.yourimage = theimage.image;
[self presentViewController: secondview animated:YES completion:NULL];
}
- (void)dealloc {
[theimage release];
[super dealloc];
}
#end

Range or index out of bounds (App is crashing)

I have an app with ads banner (inner-active) in every view controller (4 views) and i keep getting this error after 2-3-4 minutes that my app is running:
'NSRangeException', reason: '*** -[__NSCFString substringToIndex:]: Range or index out of bounds'
My app is crashing & i can't find the solution for that, but i know for sure that is something with my AD banner issue cau's when i comment the ad banner code everything works great. i can assume that it happens when new request is loading on the banner.
This is the code i'm using for the AD banner:
.h file:
#property (nonatomic, retain) UIView *adBanner;
.m file:
Did synthesize & import for what i need and after that:
- (void)viewWillAppear:(BOOL)animated
{
CGRect frame = CGRectMake(0, 430, 320, 50);
self.adBanner = [[UIView alloc] initWithFrame:frame];
[self.view addSubview:self.adBanner];
// Display ad
if (![InneractiveAd DisplayAd:#"iOS_Test" withType:IaAdType_Banner withRoot:adBanner withReload:60 withParams:optionalParams])
{
adBanner.hidden = YES;
}
}
This is my AppDelegate (don't know why but maybe it something with that too?):
.h file:
#import <UIKit/UIKit.h>
#class RootViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, strong) RootViewController *rootViewController;
#end
.m file:
#import "AppDelegate.h"
#import "RootViewController.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize rootViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.rootViewController = [[RootViewController alloc] initWithNibName:nil bundle:NULL];
[self.window addSubview:self.rootViewController.view];
[self.window makeKeyAndVisible];
return YES;
}
I realy don't understand what it could be and how it related to NSCFString :\
Thanks.
Not sure if you got an answer to this but I was getting it with this line of code when there was no internet connection.
NSString *value = [serverOutput substringWithRange:NSMakeRange(2, [serverOutput length] - 2 * 2)];
I had to protect it with a check to the internet connection and an if then statement

splash screen won't show

EDIT 1: changed the code to:
delegate.h:
#import <UIKit/UIKit.h>
#class ViewController;
#interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
ViewController *viewController;
UIImageView *splashView;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet ViewController *viewController;
#property (nonatomic, retain) IBOutlet UIImageView *splashView;
- (void)removeSplash;
#end
delegate.m:
#import "AppDelegate.h"
#import "ViewController.h"
#implementation AppDelegate
#synthesize window;
#synthesize viewController;
#synthesize splashView;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
splashView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
splashView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Splash" ofType:#"png"]];
[window addSubview:splashView];
[window bringSubviewToFront:splashView];
[window makeKeyAndVisible];
[self performSelector:#selector(removeSplash) withObject:nil afterDelay:5.0];
[window addSubview:viewController.view];
return YES;
}
- (void)removeSplash {
[splashView removeFromSuperview];
[splashView release];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
EDIT 2:
when I use:
splashView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
splashView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Splash" ofType:#"png"]];
if (splashView.image == nil) {
NSLog(#"splashView is nil");
}
it logs "splashView is nil"
My Viewcontroller is empty, just for debugging purposes.
As you probably already know, splash screens are discouraged. Since your image is Default.png, isn't it already being shown on app launch automatically?
In any case, the sleep() call is probably blocking the UI. Remove the sleep() and move the statements after it (the removeFromSuperview, etc) to another method in the app delegate. Call this method using performSelector:withObject:afterDelay:. Put the performSelector call where you currently have the sleep call.
Also, you should use the didFinishLaunchingWithOptions method instead of the old applicationDidFinishLaunching method.

Multiple Views for UITabBarController

I'm trying to build an app where I have a TabBarController with 4 entries.
When I select the first entry, a view with a UITableView shows up.
This TableView is filled with several entries.
What I would like to do is:
When an entry out of that UITableView gets selected, another view should show up; a detailview.
.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
if(self.secondView == nil) {
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondView" bundle:[NSBundle mainBundle]];
self.secondView = secondViewController;
[secondViewController release];
}
// Setup the animation
[self.navigationController pushViewController:self.secondView animated:YES];
}
}
.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface FirstViewController : UIViewController {
SecondViewController *secondView;
NSMutableArray *myData;
}
#property (nonatomic, retain) SecondViewController *secondView;
#property (nonatomic, copy, readwrite) NSMutableArray* myData;
#end
This is what I have so far.
Unfortunately.. the code runs, bit the second view does not show up.
Is your first view controller wrapped in a UINavigationController? When you set up your UITabBarController, you should add UINavigationControllers rather than your UIViewController subclasses, e.g.:
FirstViewController *viewControl1 = [[FirstViewController alloc] init];
UINavigationController *navControl1 = [[UINavigationController alloc] initWithRootViewController:viewControl1];
UITabBarController *tabControl = [[UITabBarController alloc] init];
tabControl.viewControllers = [NSArray arrayWithObjects:navControl1, <etc>, nil];
//release everything except tabControl
Also, based on your code, you don't need to keep your secondViewController as an ivar, since UINavigationController automatically retains its view controllers (and retaining it when you're not displaying it will use up unnecessary memory).

Resources