UIView Does Not Rotate - iphone

I have the following code in a UIViewController
Notepad *notepad = [[Notepad alloc] initForNewTopLevelTask:0 andDAO:self.dao];
[self.navigationController pushViewController:notepad animated:YES];
[notepad release];
The initForNewTopLevelTask:andDAO: method is:
- (id) initForNewTopLevelTask:(int) theTableSize andDAO:(DAO*) aDAO {
self.dao = aDAO;
tableSize = [[NSNumber alloc] initWithInt:theTableSize];
self.isNew = [NSNumber numberWithBool:YES];
self.isSubtask =[NSNumber numberWithBool:NO];
return self;
}
When I rotate the view nothing happens, it does not rotate. If I change the UIViewController line to:
Notepad *notepad = [[Notepad alloc] init];
It rotates fine!
The view is not part of a Tab Controller and I have implemented:
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}

you should always call up to a parent class init method in your own init methods. Atleast for any object that is at some point extending from NSObject.
See http://developer.apple.com/iphone/library/documentation/cocoa/Conceptual/ObjectiveC/Articles/ocAllocInit.html#//apple_ref/doc/uid/TP30001163-CH22-SW4
Change your init function to:
- (id) initForNewTopLevelTask:(int) theTableSize andDAO:(DAO*) aDAO {
if ( self = [super init] ) {
self.dao = aDAO;
tableSize = [[NSNumber alloc] initWithInt:theTableSize];
self.isNew = [NSNumber numberWithBool:YES];
self.isSubtask =[NSNumber numberWithBool:NO];
}
return self;
}

Related

Trouble with datasource not being called from viewWillAppear

A little background. I have taken GCCalendar which only works in portrait orientation and extended it to work in landscape similar to how the iPhone's Calendar app works. I did this by duplicating the main view class and modifying it to work in landscape. So when the phone is in portrait orientation the CGCalendar is instantiated from the apps main view controller using the original portrait view class and when in landscape orientation using the new modified landscape view class. Most of the other classes in GCCalendar are shared without modification. A few had to be duplicated as well.
I got it all working great except for an issue with the datasource. The datasource is called when the calendar is first loaded and each time the user changes the dates being viewed. Problem is I can't get the datasource call to work on the first call.
I am stumped as it works fine in portrait orientation and I cannot find any difference between the 2 versions.
Following is some of the code that shows how it gets to the datasource call the first time. Subsequent calls removes all the calendar subviews and instantiates them again with the new dates. The duplicated landscape class names end in LS. Otherwise as you can see they are identical.
Does anyone has any idea of where else I might look to resolve this issue?
Thanks,
John
--------------------------------
//App main view controller
- (void)showLandscapeCalendar {
GCCalendarLandscapeView *calendar = [[[GCCalendarLandscapeView alloc] init] autorelease];
calendar.dataSource = self;
calendar.delegate = self;
navigationController = [[UINavigationController alloc] initWithRootViewController:calendar];
[self presentModalViewController:navigationController animated:YES];
}
- (void)showPortraitCalendar {
GCCalendarPortraitView *calendar = [[[GCCalendarPortraitView alloc] init] autorelease];
calendar.dataSource = self;
calendar.delegate = self;
navigationController = [[UINavigationController alloc] initWithRootViewController:calendar];
[self presentModalViewController:navigationController animated:YES];
}
- (NSArray *)calendarEventsForDate:(NSDate *)date{
//build and return the events array
//this is the protocol datasource method
//It is supposed to run every time the date changes in the calendar
}
-------------------------------
// GCCalendarLandscapeView...
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (viewDirty) {
[self reloadDayAnimated:NO context:NULL];
viewDirty = NO;
}
viewVisible = YES;
}
- (void)reloadDayAnimated:(BOOL)animated context:(void *)context {
GCCalendarDayViewLS *nextDayView = [[GCCalendarDayViewLS alloc] initWithCalendarView:self];
}
-------------------------------
//GCCalendarDayViewLS
- (id)initWithCalendarView:(GCCalendarView *)view {
if (self = [super init]) {
dataSource = view.dataSource;
}
return self;
}
- (void)reloadData {
//** first time through the dataSource method does not run
events = [dataSource calendarEventsForDate:date];
}
-------------------------------
// GCCalendarPortraitView...
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (viewDirty) {
[self reloadDayAnimated:NO context:NULL];
viewDirty = NO;
}
viewVisible = YES;
}
- (void)reloadDayAnimated:(BOOL)animated context:(void *)context {
GCCalendarDayView *nextDayView = [[GCCalendarDayView alloc] initWithCalendarView:self];
}
-------------------------------
//GCCalendarDayView
- (id)initWithCalendarView:(GCCalendarView *)view {
if (self = [super init]) {
dataSource = view.dataSource;
}
return self;
}
- (void)reloadData {
**//this one works every time
events = [dataSource calendarEventsForDate:date];
}

back button at root controller of uinavigationcontroller

I have a UINavigationController application with a root view controller and each time I am pushing a view controller to the stack. Let's say the stack is A B C D where A is the root view controller here. The issue is that when I am at view controller D and do a popToRootViewController it went back to A but A has a back button on it. When I click on back the back just slides in and disappear, why is this happening?
EDIT: I am actually subclassing my UINavigationController so that I can set my rootViewController as follows:
#import "CustomNavigationController.h"
#implementation CustomNavigationController
#synthesize fakeRootViewController;
//override to remove fake root controller
-(NSArray *)viewControllers {
NSArray *viewControllers = [super viewControllers];
if (viewControllers != nil && viewControllers.count > 0) {
NSMutableArray *array = [NSMutableArray arrayWithArray:viewControllers];
[array removeObjectAtIndex:0];
return array; }
return viewControllers; }
//override so it pops to the perceived root
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated {
//we use index 0 because we overrided “viewControllers”
((UIViewController *)[self.viewControllers objectAtIndex:0]).navigationItem.hidesBackButton = YES;
return [self popToViewController:[self.viewControllers objectAtIndex:0] animated:animated]; }
//this is the new method that lets you set the perceived root, the previous one will be popped (released)
-(void)setRootViewController:(UIViewController *)rootViewController {
rootViewController.navigationItem.hidesBackButton = YES;
[self popToViewController:fakeRootViewController animated:NO];
[self pushViewController:rootViewController animated:NO]; }
- (void)dealloc {
self.fakeRootViewController = nil;
[super dealloc]; }
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
UIViewController *fakeController = [[[UIViewController alloc] init] autorelease];
self.fakeRootViewController = fakeController;
NSMutableArray *array = [NSMutableArray arrayWithArray:[super viewControllers]];
[array insertObject:fakeController atIndex:0];
self.viewControllers = array;
}
return self; }
- (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
/* // Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView { }
*/
/* // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad]; }
*/
- (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 (interfaceOrientation == UIInterfaceOrientationPortrait); }
#end
MORE UPDATE:
So after I set my rootViewController and then push a viewController and then tried to call popToRootViewController from that view, it all worked fine. However, if I push another viewController after the second one and then call the popToRootViewController, now I can see that weird back button on the root.
I too face the same problem. So in your root controller assign leftBarButtonItem equal to nil.
self.navigationItem.leftBarButtonItem = nil;
If your root controller reusing in the program. Then you need to check ->
BOOL needBackBarButton = (1 < [self.navigationController.viewControllers count]) ? YES : NO ;
if (! needBackBarButton)
{
self.navigationItem.leftBarButtonItem = nil;
}
For other controllers
if (needBackBarButton)
{
// Create custom navigationItem here.
}
else
{
self.navigationItem.leftBarButtonItem = nil;
}

AQGridview Not Calling Datasource Methods

I am trying to implement AQGridView based upon the ImageDemo in the /examples folder. I have a view controller with the following declaration:
#interface ImageDemoViewController : UIViewController <AQGridViewDelegate, AQGridViewDataSource, ImageDemoCellChooserDelegate>
{
...
None of the datasource methods in my view controller such as
- (NSUInteger) numberOfItemsInGridView: (AQGridView *) aGridView
{
return ( [images count] );
}
are being called. Here is where I setup the gridview making my view controller the delegate for the gridview.
- (void)viewDidLoad
{
[super viewDidLoad];
self.gridView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.gridView.autoresizesSubviews = YES;
self.gridView.delegate = self;
self.gridView.dataSource = self;
images=[[NSMutableArray alloc]init];
[images addObject:#"http://t3.gstatic.com/images?q=tbn:ANd9GcTOXAzFMoK441mcn9V0OemVe_dtAuCpGjBkLrv4rffyOjYIo45BEw"];
[self.gridView reloadData];
}
If I set a breakpoint on
[self.gridView reloadData];
the line is executed but reloadData method in AQGridView is not called. The only difference from the ImageDemo is I do not have a .xib file for the view controller. Have I forgotten to hook up something, resulting in the datasource methods not being called?
If there's no XIB, then who's creating the gridView? If it's never created, then it would be NIL, and you'd have the behavior you describe. (If that's it, then just adding:
self.gridview = [AQGridView alloc] initWithFrame: ...]; should suffice.
Had the same problem. Solved by replacing the view with the AQGridView.
[self.view addSubview:self.gridView]
self.view = self.gridView;
Full method:
- (void) viewDidLoad
{
[super viewDidLoad];
self.gridView = [[AQGridView alloc] init];
self.gridView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.gridView.autoresizesSubviews = YES;
self.gridView.delegate = self;
self.gridView.dataSource = self;
self.view = self.gridView;
[self.gridView reloadData];
}
Maybe you could try implementing this:
- (void)LoadSearch
{
NSURL *test1 = [NSURL URLWithString:#"http://www.4ddraws.com/search_iphone.asp"];
NSURLRequest *test = [NSURLRequest requestWithURL:test1];
[web4D setScalesPageToFit:(YES)];
[web4D loadRequest:test];
}

UIPageControl with UIView with button

I'm new to Objective-C and need help!
I'm following the example "PageControl" which can be found on the net. I added a button to the view in the NIB and hooked up an action which the implementation is found below.
Here is my definition for the view controller being displayed in the page control:
//ContactCardViewController.h
#interface ContactCardViewController : UIViewController
{
int pageNumber;
NSMutableString *s;
}
//ContactCardViewController.m implementation
- (id)initWithPageNumber:(int)page {
if (self = [super initWithNibName:#"ContactCardViewController" bundle:nil]) {
s = [[NSString alloc] initWithFormat:#"page: %d", page];
}
return self;
}
- (id)initWithString:(NSDictionary *)_s {
if (self = [super initWithNibName:#"ContactCardViewController" bundle:nil]) {
NSMutableString *t = [[NSMutableString alloc] initWithString:_s];
s = t;
}
return self;
}
-(IBAction)callOrAddToContacts:(id)sender
{
jobtitleLabel.text = s;
}
//AppDelegate.m
//in delegate that loads the scroll view with the view for the current page:
- (void)loadScrollViewWithPage:(int)page {
//init the view this way the page: and the correct page number is displayed
controller = [[ContactCardViewController alloc] initWithPageNumber:page ];
//init the view this way, the value of the first person is always displayed
controller = [[ContactCardViewController alloc] initWithString:[[self.allNames objectAtIndex:page] objectForKey:#"firstname"]];
}
Please help me to understand why when the view is created with initWithString and then accessed via the button action only value for the first person in the list is always returned. When i init the view using initWithPageNumber s has the correct value Page: X.
In the InitWithString code, you're passing in a Dictionary, not a string.
- (id)initWithString:(NSDictionary *)_s {
if (self = [super initWithNibName:#"ContactCardViewController" bundle:nil]) {
NSMutableString *t = [[NSMutableString alloc] initWithString:_s];
s = t;
}
return self;
}
You may want to change that to NSString, or change the NSMutableString... to an instance of NSDictionary. One or the other.
Found out the problem was in the plist file. The code is fine.

Take a random Number from one ViewController and use it in a second ViewController - Update

I have two ViewControllers: The RedButtonViewController and the TweetViewController. The RedButtonViewController generates random numbers in Textlabels and I want to use the number or the label with the TweetViewController. How can I make this?
Thanks for your help!
My TweetViewController will be opened with this code in the RedButtonViewController:
- (IBAction)TweetViewController:(id)sender {
TweetViewController *Tweet = [[TweetViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:Tweet animated:YES];
}
Here is an exemple of how I generate the random number:
- (IBAction)pushRedButton:(UIButton *)sender {
int ZahlDerToten;
ZahlDerToten = arc4random() % 1000000;
outputLabel.text = [NSString stringWithFormat:#"You killed %d people.", ZahlDerToten];
Create a property on the TweetViewController and set it before presenting it:
- (IBAction)TweetViewController:(id)sender {
// Note: don't put leading capitals on a local variable
TweetViewController *tweet = [[TweetViewController alloc] initWithNibName:nil bundle:nil];
tweet.randomNumber = [self generateRandomNumber];
[self presentModalViewController:tweet animated:YES];
// Note: You were leaking the view controller
[tweet release];
}
Another solution (and how I usually do this kind of thing) is to create a new initializer called -initWithNumber: (probably something a little more descriptive than "number") and call it like this:
- (IBAction)TweetViewController:(id)sender {
TweetViewController *tweet = [[TweetViewController alloc] initWithNumber:[self generateRandomNumber]];
[self presentModalViewController:tweet animated:YES];
[tweet release];
}
-initWithNumber would then look something like:
- (TweetViewController *)initWithNumber:(NSInteger)number {
self = [super initWithNibName:nil bundle:nil];
if (self != nil) {
self.number = number;
}
return self;
}