I have a resizing issue when rotating a view controller that has two views which I switch between using the flip animation.
The problem appears if i do the following steps:
Rotate the device when viewing the tableview.
Click the info button.
Rotate the device (infoView appears stretched).
Click on info button (tableview appears stretched)
It appears that the view that is not added to the superview is not resizing correctly, since it was not part of the composite views when the device was rotated.. Is there any way to get this view auto resized correctly?
Below is a code sample
- (void)viewDidLoad {
[super viewDidLoad];
//background image
backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bg-app.png"]];
backgroundImageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
[self.view addSubview: backgroundImageView];
[backgroundImageView release];
//infoView
aboutImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"About.png"]];
aboutImageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
//tableView
self.tableView = [[[UITableView alloc ] initWithFrame:[[UIScreen mainScreen] bounds] style:UITableViewStylePlain] autorelease ];
//set the rowHeight once for performance reasons.
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.rowHeight = 75;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.autoresizesSubviews = YES;
//set the rowHeight once for performance reasons.
[self.view addSubview: tableView];
//[tableView release];
[self.view setAutoresizingMask:UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth];//for resizing on rotation
//info button
UIButton * infoDarkButtonType = [[UIButton buttonWithType:UIButtonTypeInfoLight] retain];
infoDarkButtonType.frame = CGRectMake(0.0, 0.0, 25.0, 25.0);
infoDarkButtonType.backgroundColor = [UIColor clearColor];
[infoDarkButtonType addTarget:self action:#selector(infoAction:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *buttonInfo = [[UIBarButtonItem alloc] initWithCustomView:infoDarkButtonType];
self.navigationItem.rightBarButtonItem = buttonInfo;
[infoDarkButtonType release];
self.navigationItem.rightBarButtonItem = buttonInfo;
[buttonInfo release];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}
- (void)infoAction:(id)sender{
NSLog(#"Clicked on the info button");
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75]; /* Sub. duration here */
UIView *superview;
if ((superview = [tableView superview])) {
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:superview cache:YES];
[tableView removeFromSuperview];
[superview addSubview:aboutImageView];
} else if ((superview = [aboutImageView superview])) {
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:superview cache:YES];
[aboutImageView removeFromSuperview];
[superview addSubview:tableView];
}
[UIView commitAnimations];
}
Thanks
Try putting the code in viewWillAppear:animated. It's called every time your view will appear. View did load is called once.
Related
I am trying to replicate the screen in the middle, namely the alert that is displayed to compose a new tweet. I have tried to duplicate it with a custom UIAlertView but that requires a lot of subclassing and what not, then I suspected it might just be a simple UIViewController that is displayed over the main view... professional thoughts from fellow iOS developers is needed.
Thank you.
In iPad:
You can do it with a UIViewController.
You need to design UI according to the above image.
Then you need to set the Modal Presentation Style to UIModalPresentationFormSheet
And present it using - (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))
Like:
UIViewController *viewC = [[UIViewController alloc] init];
viewC.view.frame = //set the frame;
viewC.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:viewC animated:YES completion:nil];
In iPhone:
You can do it with using a UIView.
You can use the following code for doing this:
Declare a property in your interface
#property (nonatomic, strong) UIView *views;
//Add the view
- (void) showView
{
UIToolbar *toolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 35)];
UIBarButtonItem *bar = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(remove)];
toolbar.items = [NSArray arrayWithObject:bar];
_views = [[UIView alloc] initWithFrame:CGRectMake(0, -300, self.view.bounds.size.width, self.view.bounds.size.height/3)];
[_views addSubview:toolbar];
[_views setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:_views];
[UIView animateWithDuration:0.7
delay:0.0
options:UIViewAnimationCurveLinear
animations:^{
_views.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/3);
}
completion:^(BOOL yes){
NSLog(#"YO");
}];
[UIView commitAnimations];
}
//Remove the view
- (void)remove
{
[UIView animateWithDuration:0.7
delay:0.0
options:UIViewAnimationCurveLinear
animations:^{
_views.frame = CGRectMake(0, -500, self.view.bounds.size.width, self.view.bounds.size.height/3);
}
completion:^(BOOL yes){
NSLog(#"YA");
}];
[UIView commitAnimations];
}
I am using view.bounds to determine where to add a date picker view when a button is pressed. This works just fine if the orientation if the same as it was when the view was navigated to. Unfortunately if the orientation changes while the view is displayed the bounds are not undated, so the picker view is displayed incorrectly. I need a way to determine the actually bounds of the view. I would like something that works in both iPad and iPhone if possible because this is for a universal app. Also in the iPad version the picker view is in a splitview detail controller so I can't just swap the height and width and adjust for the navigation bar.
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
// size up the picker view to our screen and compute the start/end frame origin for our slide up animation
//
// compute the start frame
CGRect screenRect = self.view.bounds;
CGSize pickerSize = [self.pickerView sizeThatFits:CGSizeZero];
CGRect startRect;
CGRect pickerRect;
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsPortrait(orientation))
{
// code for Portrait orientation
startRect = CGRectMake(0.0,
screenRect.origin.y + screenRect.size.height,
pickerSize.width, pickerSize.height);
pickerRect = CGRectMake(0.0,
screenRect.origin.y + screenRect.size.height - pickerSize.height,
screenRect.size.width,
pickerSize.height);
}
else
{
//code for landscape
startRect = CGRectMake(0.0,
screenRect.origin.y + screenRect.size.height,
pickerSize.width, pickerSize.height);
pickerRect = CGRectMake(0.0,
screenRect.origin.y + screenRect.size.height - pickerSize.height,
screenRect.size.width,
pickerSize.height);
}
self.pickerView.frame = startRect;
// start the slide up animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
// we need to perform some post operations after the animation is complete
[UIView setAnimationDelegate:self];
self.pickerView.frame = pickerRect;
}
If I understand correctly your issue, you should try and set:
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
on your views so that they bounds are "updated" when the orientation changes.
I ended up adding the pickerview to an action sheet like so:
UIActionSheet *aac = [[UIActionSheet alloc] initWithTitle:#"Choose Date and Time"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[datePicker addTarget:self action:#selector(dateChanged) forControlEvents:UIControlEventValueChanged];
pickerDateToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
pickerDateToolbar.barStyle = UIBarStyleBlackOpaque;
[pickerDateToolbar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(DatePickerDoneClick)];
[barItems addObject:doneBtn];
[pickerDateToolbar setItems:barItems animated:YES];
[aac addSubview:pickerDateToolbar];
[aac addSubview:datePicker];
[aac showFromTabBar:self.tabBarController.tabBar];
CGFloat wideth = self.view.frame.size.width;
if (UIDeviceOrientationIsLandscape([self interfaceOrientation])) {
[aac setBounds:CGRectMake(0,0,wideth, 355)];
[datePicker sizeToFit];
} else {
[aac setBounds:CGRectMake(0,0, wideth, 470)];
[datePicker sizeToFit];
}
picker = aac;
Hope that this helps others.
I am creating a app that display subview like ActionSheetView and in that i have added UIGridView and UIPageControll thru outlet , but now when i click the cell it does not respond ,my subview is a ViewController with the nib file.
and if i create a button and add in my popupview programmatically then it wil displaying, and also get the click event, but anything in outlet does not respond.
i have tried to set userinteraction enable in my subview but it does not done any good.
here is my code for first view that display subview by clicking barbutton:
- (void)popUpView:(id)sender {
//self.view.backgroundColor = [UIColor darkGrayColor];
bGView = [[UIView alloc] init]; /this is the background view and all view is added in it
bGView.frame = CGRectMake(0,0,320,490);
bGView.backgroundColor = [UIColor clearColor];
bGView.alpha = 0.8 ;
CGRect viewFrame = CGRectMake(10, 90, 300, 300);
aPopUpViewController = [[PopUpViewController alloc] initWithNibName:#"PopUpViewController" bundle:nil]; //this is my view controller and when this shows on screen it display my greed view
aPopUpViewController.view.frame = viewFrame;
aPopUpViewController.view.userInteractionEnabled = YES;
[bGView addSubview:aPopUpViewController.view];
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
button.backgroundColor = [UIColor clearColor];
[button setBackgroundImage:[UIImage imageNamed:#"close_button.png"] forState:UIControlStateNormal];
button.frame = CGRectMake(-1, 80, 30, 30);
[bGView addSubview:button];
//for view animation
/*
// from bottom to center animation
[bGView setFrame:CGRectMake( 0.0f, 480.0f, 320.0f, 480.0f)]; //notice this is OFF screen!
[UIView beginAnimations:#"animateTableView" context:nil];
[UIView setAnimationDuration:0.4];
[bGView setFrame:CGRectMake( 0.0f, 0.0f, 320.0f, 480.0f)]; //notice this is ON screen!
[UIView commitAnimations];*/
//for page like effect
/*[UIView transitionWithView:self.view duration:0.5
options:UIViewAnimationOptionTransitionCurlUp //change to whatever animation you like
animations:^ { [self.view addSubview:bGView]; }
completion:nil];*/
/*CATransition *transition = [CATransition animation];
transition.duration = 1.0;
transition.type = kCATransitionReveal; //choose your animation
[bGView.layer addAnimation:transition forKey:nil];
[self.view addSubview:bGView];*/
aPopUpViewController.view.userInteractionEnabled = YES;
bGView.userInteractionEnabled = YES;
self.view.userInteractionEnabled = YES;
bGView.transform = CGAffineTransformMakeScale(0.01, 0.01);
[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
bGView.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished){
// do something once the animation finishes, put it here
}];
[self.view addSubview:bGView];
addLabel.enabled = NO;
clipArt.enabled = NO;
emailItem.enabled = NO;
closeButton.enabled = NO;
self.navigationController.topViewController.title = #"Choose ClipArt";
ExampleAppDataObject* theDataObject = [self theAppDataObject];
theDataObject.navBarHide = #"no";
}
- (void)aMethod:(id)sender
{
//[aPopUpViewController.view removeFromSuperview];
//[button removeFromSuperview];
/*[UIView transitionWithView:self.view duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve//change to whatever animation you like
animations:^ { [bGView removeFromSuperview]; }
completion:nil];*/
[bGView removeFromSuperview];
addLabel.enabled = YES;
clipArt.enabled = YES;
emailItem.enabled = YES;
closeButton.enabled = YES;
self.navigationController.topViewController.title = #"Greeting's";
ExampleAppDataObject* theDataObject = [self theAppDataObject];
theDataObject.navBarHide = #"yes";
}
and this is how my screen look like
UPDATE
now i figured out my problem,problem is that i have given my whole view a tap listner,now i am adding grid view as subview so when ever i tap on cell rather then do select cell it will generate view tap gesture and thats why cell never selected,that's what i think..
add this line after you add every subviews in your main view..
[self.view bringSubviewToFront:yourGridView];
Since when I click the UITextField the date picker is showing along with the keyboard, I want to hide the key board operation on dob-text field?Here my code
- (void)removeViews:(id)object
{
[[self.view viewWithTag:9] removeFromSuperview];
[[self.view viewWithTag:10] removeFromSuperview];
[[self.view viewWithTag:11] removeFromSuperview];
}
- (void)dismissDatePicker:(id)sender
{
CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height, 320, 44);
CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height+44, 320, 216);
[UIView beginAnimations:#"MoveOut" context:nil];
[self.view viewWithTag:9].alpha = 0;
[self.view viewWithTag:10].frame = datePickerTargetFrame;
[self.view viewWithTag:11].frame = toolbarTargetFrame;
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(removeViews:)];
[UIView commitAnimations];
}
- (IBAction)but
{
//[eventText resignFirstResponder];
[dob resignFirstResponder];
if ([self.view viewWithTag:9])
{
return;
}
CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height-216-44, 320, 44);
CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height-216, 320, 216);
UIView *darkView = [[UIView alloc] initWithFrame:self.view.bounds ];
darkView.alpha = 0;
darkView.backgroundColor = [UIColor blackColor];
darkView.tag = 9;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissDatePicker:)] ;
[darkView addGestureRecognizer:tapGesture];
[self.view addSubview:darkView];
datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height+44, 320, 216)] ;
datePicker.datePickerMode=UIDatePickerModeDate;
datePicker.tag = 10;
[datePicker addTarget:self action:#selector(changeDate:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:datePicker];
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, 320, 44)] ;
toolBar.tag = 11;
toolBar.barStyle = UIBarStyleBlackTranslucent;
UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil] ;
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissDatePicker:)] ;
[toolBar setItems:[NSArray arrayWithObjects:spacer, doneButton, nil]];
[self.view addSubview:toolBar];
[UIView beginAnimations:#"MoveIn" context:nil];
toolBar.frame = toolbarTargetFrame;
datePicker.frame = datePickerTargetFrame;
darkView.alpha = 0.5;
[UIView commitAnimations];
//[datePicker addTarget:self action:#selector(dateText:)forControlEvents:UIControlEventValueChanged];
//NSDateFormatter *_dateFormatter = [[NSDateFormatter alloc] init];
//_dateFormatter.dateStyle = NSDateFormatterFullStyle;
//dateText.text = [NSString stringWithFormat:#"%#",
// [_dateFormatter stringFromDate:datePicker.date]];
//[self.tableview reloadData];
}
I added the resignfirstresponder also,since its showing the same error
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
return [textField resignFirstResponder];
return [txt1 resignFirstResponder];//dob textfield
}
Use UITextField's delegate method
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textField == dob-text )
//load picker here
return NO; //hide keyboard
else
return YES; //show keyboard
}
A better solution is to set the UIPickerView as the inputView for the UITextField.
And you can set the UIToolBar as the inputAccessoryView of the inputView.
This way iOS will handle the displaying of all UIPickView.
Just set the properties top the correct views:
self.dateTextField.inputView = self.datePicker;
self.dateTextField.inputAccessoryView = self.inputToolbar;
On another note, getting views with viewWithTag: methods means that the you are looping thru all the views. Why not create properties for these views. It will be less messy and might be faster.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
datePicker.hidden = NO;
[textField resignFirstResponder];
}
try in textFieldDidBeginEditing
-(void) textFieldDidBeginEditing:(UITextField *)textField{
[textField resignFirstResponder];
}
First of all a textfield should not have a popover - neither picker nor popover nor anything
Best solution would be to put a button - type custom - set image like a date selector image and add selector - in that case you would n't have any issues w.r.t textfields popover and the look would be good as well and you can customize it as per your requirement.
I have a UIView with another UIView inside it. On the inside UIView there is a textbox which I want to fill in. When I try to fill it in the keyboard blocks my view:
The UIViewController has the following
containerView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.view=containerView;
//The apropriate releases etc are further on...
When I touch it, the keyboard comes up as expected, but blocks the textbox I'm trying to fill in. How can I force the view to slide up?
The front view
OptionsFront * fv = [[OptionsFront alloc] initWithFrame:[UIScreen mainScreen].bounds];
[containerView addSubview:frontView];
In the front view is a subview
CGRect bounds = CGRectMake(0.0f, 210.0f, 280.0f, 130.0f);
sv = [[UIView alloc] initWithFrame:bounds];
[self addSubview:sv]; //added to frontView
In sv is a textbox near the botton:
rect = CGRectMake(70.0f, 20.0f, 100.0f, 27.0f);
cf = [self createTextField_Rounded:rect holder:#"+ve"];
[sv addSubview:cf];
So cf happens to be near the bottom of the page. I expected that when I select it, the whole display would move up, but the keyboard just moves up and blocks it.
What can I do?
Appendix:
- (UITextField *)createTextField_Rounded:(CGRect) frame holder:(NSString *) ph
{
UITextField *returnTextField = [[UITextField alloc] initWithFrame:frame];
returnTextField.borderStyle = UITextBorderStyleRoundedRect;
returnTextField.textColor = [UIColor blackColor];
returnTextField.font = [UIFont systemFontOfSize:17.0];
returnTextField.delegate = self;
returnTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
returnTextField.returnKeyType = UIReturnKeyDone;
returnTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
return returnTextField;
}
you need to move the textField up. in your UITextField delegate implement something like (from memory):
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
textField.superview.frame = CGRectMake(0.0f, 100.0f, 280.0f, 130.0f); // experiment with frame size
[UIView commitAnimations];
}
and you'll want to move it back in textFieldDidEndEditing: