Set Admob banner to appear at bottom of screen - iphone

I am currently using this code to display an Admob request;
If I use this code, the banner appears, but at the top of the screen not the bottom;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
CGFloat screenXPos = (screenWidth/2);
CGFloat screenYPos = screenHeight - kGADAdSizeBanner.size.height;
[bannerView_ setCenter:CGPointMake(screenXPos, screenYPos)];
bannerView_ = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerLandscape];
bannerView_.adUnitID = ADMOB_ID;
bannerView_.rootViewController = self;
bannerView_.adUnitID = ADMOB_ID;
bannerView_.rootViewController = self;
[self.view addSubview:bannerView_];
[bannerView_ loadRequest:[GADRequest request]];
How would I change this to show at the bottom of the screen instead?

METHOD 1: Put this code in bottom of your code.
//TRY_1:
bannerView_.frame = CGRectMake(screenWidth/2.0 - bannerView_.frame.size.width/2.0, screenHeight - bannerView_.frame.size.height,
bannerView_.frame.size.width,bannerView_.frame.size.height);
//OR TRY_2:
bannerView_.frame = CGRectMake(screenHeight/2.0 - bannerView_.frame.size.width/2.0, screenWidth - bannerView_.frame.size.height,
bannerView_.frame.size.width,bannerView_.frame.size.height);
METHOD 2: Detailed clean way
typedef enum _bannerType
{
kBanner_Portrait_Top,
kBanner_Portrait_Bottom,
kBanner_Landscape_Top,
kBanner_Landscape_Bottom,
}CocosBannerType;
//In .h declare CocosBannerType mBannerType;
-(void)createAdmobAds
{
mBannerType = kBanner_Portrait_Bottom; //kBanner_Portrait_Top
AppController *app = (AppController*)[[UIApplication sharedApplication] delegate];
// Create a view of the standard size at the bottom of the screen.
// Available AdSize constants are explained in GADAdSize.h.
if(mBannerType <= kBanner_Portrait_Bottom)
mBannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait];
else
mBannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerLandscape];
// Specify the ad's "unit identifier." This is your AdMob Publisher ID.
mBannerView.adUnitID = MY_BANNER_UNIT_ID;
// Let the runtime know which UIViewController to restore after taking
// the user wherever the ad goes and add it to the view hierarchy.
mBannerView.rootViewController = app.navController;
[app.navController.view addSubview:mBannerView];
// Initiate a generic request to load it with an ad.
[mBannerView loadRequest:[GADRequest request]];
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGSize s = screenRect.size;
CGRect frame = mBannerView.frame;
off_x = 0.0f;
on_x = 0.0f;
switch (mBannerType)
{
case kBanner_Portrait_Top:
{
off_y = -frame.size.height;
on_y = 0.0f;
}
break;
case kBanner_Portrait_Bottom:
{
off_y = s.height;
on_y = s.height-frame.size.height;
}
break;
case kBanner_Landscape_Top:
{
off_y = -frame.size.height;
on_y = 0.0f;
}
break;
case kBanner_Landscape_Bottom:
{
off_y = s.height;
on_y = s.height-frame.size.height;
}
break;
default:
break;
}
frame.origin.y = off_y;
frame.origin.x = off_x;
mBannerView.frame = frame;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
frame = mBannerView.frame;
frame.origin.x = on_x;
frame.origin.y = on_y;
mBannerView.frame = frame;
[UIView commitAnimations];
}
-(void)showBannerView
{
if (mBannerView)
{
[UIView animateWithDuration:0.5
delay:0.1
options: UIViewAnimationCurveEaseOut
animations:^
{
CGRect frame = mBannerView.frame;
frame.origin.y = on_y;
frame.origin.x = on_x;
mBannerView.frame = frame;
}
completion:^(BOOL finished)
{
}];
}
}
-(void)hideBannerView
{
if (mBannerView)
{
[UIView animateWithDuration:0.5
delay:0.1
options: UIViewAnimationCurveEaseOut
animations:^
{
CGRect frame = mBannerView.frame;
frame.origin.y = off_y;
frame.origin.x = off_x;
}
completion:^(BOOL finished)
{
}];
}
}
-(void)dismissAdView
{
if (mBannerView)
{
[UIView animateWithDuration:0.5
delay:0.1
options: UIViewAnimationCurveEaseOut
animations:^
{
CGRect frame = mBannerView.frame;
frame.origin.y = off_y;
frame.origin.x = off_x;
mBannerView.frame = frame;
}
completion:^(BOOL finished)
{
[mBannerView setDelegate:nil];
[mBannerView removeFromSuperview];
mBannerView = nil;
}];
}
}

You can check the solution proposed in Google Ads developer blog:
http://googleadsdeveloper.blogspot.com/2012/06/keeping-smart-banner-docked-to-bottom.html
// Initialize the banner docked to the bottom of the screen.
// We start in a portrait orientation so use kGADAdSizeSmartBannerPortrait.
CGPoint origin = CGPointMake(0.0,
self.view.frame.size.height -
CGSizeFromGADAdSize(
kGADAdSizeSmartBannerPortrait).height);
self.adBanner = [[[GADBannerView alloc]
initWithAdSize:kGADAdSizeSmartBannerPortrait
origin:origin] autorelease];
//Continue rest of initialization here
Make sure to use self.view.frame.size.width in the Y coordinate of the origin if you are using kGADAdSizeSmartBannerLandscape.

Related

Customize Scrolling indicator

Is there a way to customize scrolling indicator(vertical or horizontal) in UIScrollView. For example, change it's color or position in scrollview.
First, you have to uncheck showVerticalIndicator and showHorizontallIndicator in the Interface Builder.
Then in the viewDidLoad method add :
[super viewDidLoad];
self.scrollViewBarImgView = [[UIImageView alloc] init];
UIImage *imgBar = [UIImage imageNamed:#"scroller.png"];
[self.scrollViewBarImgView setImage:imgBar];
CGRect frame = scrollViewBarImgView.frame;
frame.size.width = 8;
frame.size.height = 60;
frame.origin.x = 312;
frame.origin.y = 0;
[self.scrollViewBarImgView setFrame:frame];
[self.tableView addSubview:scrollViewBarImgView];
then in the - (void)scrollViewDidScroll method :
CGPoint offset = scrollView.contentOffset;
CGRect frame = self.scrollViewBarImgView.frame;
float fact = (cellHeight*numberOfRow+ indicatorBarHeight) / tableViewHeight;
frame.origin.y = offset.y + (offset.y/fact);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.1];
[self.scrollViewBarImgView setFrame:frame];
[UIView commitAnimations];
This is working for me.

keyboards hide entering text

I am working on QuickDialog at here
However, my view can not scroll and the keyboard is hiding the entering text. What I am having so far is
- (void)loadView {
self.navigationController.navigationBarHidden = NO;
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
self.navigationItem.hidesBackButton = NO;
NSLog(#"LOAD VIEW");
self.root = [[QRootElement alloc] init] ;
self.root.controllerName = #"CreateAccountViewController";
self.root.grouped = YES;
self.root.title = #"Registration";
[super loadView];
QSection *section1 = [[QSection alloc] init];
// Create title cell
QEntryElement *cell1 = [[QEntryElement alloc] init];
cell1.title = #"Title: ";
cell1.key = #"title";
cell1.placeholder = #"Mr/Mrs/Miss";
cell1.hiddenToolbar = YES;
cell1.autocapitalizationType = UITextAutocapitalizationTypeNone;
cell1.autocorrectionType = UITextAutocorrectionTypeNo;
// Create firstName cell
QEntryElement *cell2 = [[QEntryElement alloc] init];
cell2.title = #"FirstName: ";
cell2.key = #"firstName";
cell2.placeholder = #"Enter your first name";
cell2.hiddenToolbar = YES;
cell2.autocapitalizationType = UITextAutocapitalizationTypeNone;
cell2.autocorrectionType = UITextAutocorrectionTypeNo;
// Create lastName cell
QEntryElement *cell3 = [[QEntryElement alloc] init];
cell3.title = #"LastName: ";
cell3.key = #"lastName";
cell3.placeholder = #"Enter your last name";
cell3.hiddenToolbar = YES;
cell3.autocapitalizationType = UITextAutocapitalizationTypeNone;
cell3.autocorrectionType = UITextAutocorrectionTypeNo;
// Create phone number cell
QEntryElement *cell4 = [[QEntryElement alloc] init];
cell4.title = #"Phone: ";
cell4.key = #"phoneNumber";
cell4.placeholder = #"Enter your phone number";
cell4.hiddenToolbar = YES;
cell4.autocapitalizationType = UITextAutocapitalizationTypeNone;
cell4.autocorrectionType = UITextAutocorrectionTypeNo;
.............................
.............................
[main addElement:cell1];
[main addElement:cell2];
[main addElement:cell3];
[main addElement:cell4];
[main addElement:cell5];
[main addElement:cell6];
[main addElement:cell7];
[self.root addSection:section];
After running it, i realized that the keyboard is hiding the context because I have a long list of input. Also, the view is not scrollable at all
There are an attached image at here that you can see my problem...
![enter image description here][3]
I went thru the sample code and the view is scrollable so that the keyboard is not going to hide any text at all.
Does any body have any ideas about this issue, please help. All comments are welcomed here
Just for this record, since this question was asked, this has been implemented in QuickDialog, so you don't have to worry about it anymore.
One way to solve this problem is to resize the scroll view to [screen height] - [height of keyboard] (this is coming from a similar post that I saw somewhere).
You might want to try that.
There are 2 possible ways.
To change the view height when keyboard opens or closes.
To change the view origin when keyboard opens or closes.
Implementing this code in the two delegate methods of your textField will do what you want. Here is the textFieldDidBeginEditing:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator =
midline - viewRect.origin.y
- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
heightFraction = 1.0;
}
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown)
{
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
And here is the textFieldDidEndEditing:
- (void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[self textFieldShouldReturn:textField];
[UIView commitAnimations];
}
If you want it for the buttons you can just setup an IBAction with the above code.

I want to place imageview at different position with animation

I am trying to set multiple image on different position this is my code anyone help me to set imageview on different position.
- (void)viewDidLoad
{
[super viewDidLoad];
frameX = 45.0f;
frameY = 60.0f;
imagearr = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"King2.png"],
[UIImage imageNamed:#"3.png"],[UIImage imageNamed:#"queen.png"],
[UIImage imageNamed:#"King.png"],nil];
}
-(IBAction)hidebtn:(id)sender
{
[btn setHidden:TRUE];
[self setCards];
}
-(void)setCards
{
CGFloat dx = self.view.frame.size.width/2;
CGFloat dy = self.view.frame.size.height/2;
[cards setAnimationImages:imagearr];
CGRect frame = cards.frame;
frame.size.width = frameX;
frame.size.height = frameY;
[cards setFrame:frame];
cards.animationRepeatCount = 1;
for (int i=0; i<5;i++)
{
[UIView beginAnimations:#"Move" context:nil];
[UIView setAnimationDuration:0.3];
switch (i)
{
- (void)viewDidLoad
{
[super viewDidLoad];
frameX = 45.0f;
frameY = 60.0f;
imagearr = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"King2.png"],
[UIImage imageNamed:#"3.png"],[UIImage imageNamed:#"queen.png"],
[UIImage imageNamed:#"King.png"],nil];
}
-(IBAction)hidebtn:(id)sender
{
[btn setHidden:TRUE];
[self setCards];
}
-(void)setCards
{
CGFloat dx = self.view.frame.size.width/2;
CGFloat dy = self.view.frame.size.height/2;
[cards setAnimationImages:imagearr];
CGRect frame = cards.frame;
frame.size.width = frameX;
frame.size.height = frameY;
[cards setFrame:frame];
cards.animationRepeatCount = 1;
for (int i=0; i<5;i++)
{
[UIView beginAnimations:#"Move" context:nil];
[UIView setAnimationDuration:0.3];
switch (i)
{
case 0:
[cards setCenter:CGPointMake(dx, dy-120.0)];
cards.transform = CGAffineTransformMakeRotation(0);
break;
default:
break;
}
[self.view addSubview:cards];
[UIView commitAnimations];
}
default:
break;
}
[self.view addSubview:cards];
[UIView commitAnimations];
}
You are adding subviews too late, you can't animate what is not on screen. Add them before you start animations on some position then animate to the target position.

How do I get UITextView to scroll properly when the keyboard is visible

I have a UITextView sitting on top of a UIView, and if I tap on it to open it for editing, then the keyboard is blocking the bottom of the view and I can not see it even though I can write in this area. Can I tell the UITextView to have a different scroll area or what is the solution?
A better solution, specially for iOS 7, would be to adjust the content inset property of the textview instead of its frame, this way, the keyboard will blur the text that falls behinds it like in any other iOS 7 app. You'll also have to adjust the scroll indicators to match.
Expanding Lindemann's answer,
- (void)keyboardWasShown:(NSNotification*)notification {
NSDictionary* info = [notification userInfo];
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
self.textView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);
self.textView.scrollIndicatorInsets = self.textView.contentInset;
}
- (void)keyboardWillBeHidden:(NSNotification*)notification {
self.textView.contentInset = UIEdgeInsetsZero;
self.textView.scrollIndicatorInsets = UIEdgeInsetsZero;
}
An easy solution is to implement the UITextViewDelegate Methods
- (void)textViewDidBeginEditing:(UITextView *)textView
and
- (void)textViewDidEndEditing:(UITextView *)textView
You can make the UITextView Frame smaller when the keyboard appears and make it full size again when the keyboard disappears...like this:
- (void)textViewDidBeginEditing:(UITextView *)textView {
self.textView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height/1.8);
}
- (void)textViewDidEndEditing:(UITextView *)textView {
self.textView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
EDIT
The solution above is bad...don't use it!!!
Now I think it's a better idea to resize the UITextView in proportion to the keyboard size and not with a fixed value...because the size of the keyboard can change when an other language become chosen or the device become rotated...of course -.-
At first you must register your UIViewController which displays your UITextView for receiving Keyboard Notifications:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
Then you have to implement the two methods -keyboardWasShown: and
-keyboardWillBeHidden:.
The size of the actual keyboard is contained in the NSNotification object.
- (void)keyboardWasShown:(NSNotification*)notification {
NSDictionary* info = [notification userInfo];
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
self.textView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - keyboardSize.height);
}
- (void)keyboardWillBeHidden:(NSNotification*)notification {
self.textView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
If you want a Messages App style input, you can use a nested UITextView (allows for multiple lines of text). It will look like this in the end:
You start by laying out a view to hold all the child views. Here the background colour of the bottomView is set to match UIKeyboardAppearanceDark. It rests at the bottom of the screen.
bottomView = [UIView new];
bottomView.frame = CGRectMake(0, h-45, w, 45);
bottomView.backgroundColor = [UIColor colorWithRed:0.078 green:0.078 blue:0.078 alpha:1];
[self.view addSubview:bottomView];
Then, add in a simple background view styled like a typical UITextField, and add the UITextView as a subview to that. The inputTV (UITextView) takes its height based upon the size of the font. Also, all the padding is removed from inputTV using the textContainer variables.
inputTVBG = [UIImageView new];
inputTVBG.frame = CGRectMake(10, 8, w-90, 29);
inputTVBG.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.1f];
inputTVBG.layer.cornerRadius = 4.0f;
inputTVBG.userInteractionEnabled = true;
inputTVBG.clipsToBounds = true;
[bottomView addSubview:inputTVBG];
inputTV = [UITextView new];
inputTV.font = [UIFont systemFontOfSize:14.0f];
inputTV.frame = CGRectMake(5, 6, w-100, inputTV.font.lineHeight);
inputTV.backgroundColor = [UIColor clearColor];
inputTV.keyboardAppearance = UIKeyboardAppearanceDark;
inputTV.delegate = self;
inputTV.autocorrectionType = UITextAutocorrectionTypeNo;
inputTV.tintColor = [UIColor whiteColor];
inputTV.textColor = [UIColor whiteColor];
inputTV.textContainer.lineFragmentPadding = 0;
inputTV.textContainerInset = UIEdgeInsetsZero;
[inputTVBG addSubview:inputTV];
In the example above, I've included a label indicating how many letters are left (max / min characters) and a submit button.
lettersLeftLabel = [UILabel new];
lettersLeftLabel.frame = CGRectMake(w-70, 8, 60, 16);
lettersLeftLabel.font = [UIFont systemFontOfSize:12.0f];
lettersLeftLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.5f];
lettersLeftLabel.alpha = 0.0f;
[bottomView addSubview:lettersLeftLabel];
submitButton = [UIButton new];
submitButton.frame = CGRectMake(w-70, 0, 60, 45);
[submitButton setTitle:#"SUBMIT" forState:UIControlStateNormal];
[submitButton setTitleColor:[_peacock.applePink colorWithAlphaComponent:0.5f] forState:UIControlStateNormal];
[submitButton addTarget:self action:#selector(submit) forControlEvents:UIControlEventTouchUpInside];
[submitButton.titleLabel setFont:[UIFont boldSystemFontOfSize:14.0f]];
[bottomView addSubview:submitButton];
Add this line early on in your code, so you get keyboard change updates:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
It calls the method below when a user clicks on the inputTV. Here it sets the variable 'keyboardHeight' used later on.
-(void)keyboardWillShow:(NSNotification *)n {
CGRect rect = [n.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardFrame = [self.view convertRect:rect fromView:nil];
keyboardHeight = keyboardFrame.size.height;
[self textViewDidChange:inputTV];
}
This is the main bit of code that takes care of all the movement and resizing of the inputTV.
-(void)textViewDidChange:(UITextView *)textView {
//1. letters and submit button vars
int numberOfCharacters = (int)textView.text.length;
int minCharacters = 50;
int maxCharacters = 400;
int remainingCharacters = maxCharacters-numberOfCharacters;
//2. if entered letters exceeds maximum, reset text and return
if (remainingCharacters <= 0){
textView.text = [textView.text substringToIndex:maxCharacters];
numberOfCharacters = maxCharacters;
}
//3. set height vars
inputTV.scrollEnabled = true;
float textHeight = textView.contentSize.height;
float lineHeight = roundf(textView.font.lineHeight);
float additionalHeight = textHeight - lineHeight;
float moveUpHeight = keyboardHeight + additionalHeight;
//4. default letter colour is weak white
UIColor * letterColour = [[UIColor whiteColor] colorWithAlphaComponent:0.5f];
if (numberOfCharacters < minCharacters){ //minimum threshold not met
lettersLeftLabel.text = [NSString stringWithFormat:#"%i", minCharacters-numberOfCharacters];
letterColour = [_peacock.applePink colorWithAlphaComponent:0.5f];
} else { //within range
lettersLeftLabel.text = [NSString stringWithFormat:#"%i/%i", numberOfCharacters, maxCharacters];
if (remainingCharacters<5){ //increase alpha towards the end of range
letterColour = [[UIColor whiteColor] colorWithAlphaComponent:1.0f - ((float)remainingCharacters/10)];
}
}
//5. hide/show letter label based on textView height
float letterAlpha = 0.0f; //default hide
if (additionalHeight > 0){ letterAlpha = 1.0f; } //if multiline, show
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
lettersLeftLabel.alpha = letterAlpha;
lettersLeftLabel.textColor = letterColour;
}
completion:^(BOOL finished){
}];
//6. update submit colour based on minimum threshold
UIColor * submitColour = [_peacock.applePink colorWithAlphaComponent:0.5f];
bool enableSubmit = false;
if (numberOfCharacters >= minCharacters){
submitColour = _peacock.applePink;
enableSubmit = true;
}
[submitButton setEnabled:enableSubmit];
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[submitButton setTitleColor:submitColour forState:UIControlStateNormal];
}
completion:^(BOOL finished){
}];
//7. special case if you want to limit the frame size of the input TV to a specific number of lines
bool shouldEnableScroll = false;
int maxNumberOfLines = 5; //anything above this triggers the input TV to stay stationary and update its scroll
int actualNumberOfLines = textHeight / textView.font.lineHeight;
if (actualNumberOfLines >= maxNumberOfLines){ //recalculate vars for frames
textHeight = maxNumberOfLines * lineHeight;
additionalHeight = textHeight - lineHeight;
moveUpHeight = keyboardHeight + additionalHeight;
shouldEnableScroll = true;
}
//8. adjust frames of views
inputTV.frame = CGRectMake(5, 6, w-100, textHeight); //update immediately (parent view clips to bounds)
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
bottomView.frame = CGRectMake(0, h-45-moveUpHeight, w, 45+additionalHeight);
inputTVBG.frame = CGRectMake(10, 8, w-90, lineHeight+additionalHeight+13);
submitButton.frame = CGRectMake(w-70, additionalHeight, 60, 45);
}
completion:^(BOOL finished){
inputTV.scrollEnabled = shouldEnableScroll; //default disable scroll here to avoid bouncing
}];
}
In the above method, this is what's happening:
If you want to set a minimum or maximum number of characters, you can do so here. You pull the the number of characters and store as an integer, and calculate how many characters are left.
If the user has reached the maximum number of characters, reset the textView text by stripping back to your max.
These vars are used to calculate how much you need to move your bottomView up and also for the resizing its subviews.
This method is just to change the colour / text of some UI elements. It's not strictly necessary.
This method brings the lettersLeftLabel onto view if you're using that. It's not necessary either.
This enables the submit button only if the minimum number of characters has been reached. It changes the colour as an indicator to the user.
If you want to limit the growth of the inputTV and surrounding elements, you can include this bit of code. It requires you to set the maximum number of lines you want to show. If the user exceeds the max, scroll is reenabled for the inputTV, otherwise it defaults to false (important to stop it bouncing).
This is the main resizing logic, moving the bottomView up and resizing its child views. The submit button needs to stay in the same position, so move it down as the bottomView grows.
NOTE: If you just want the barebones code, you only need to implement steps 3 and 8.
Apple has some code samples that deal with this exact situation.
I finally got it working. Here is my solution, can you guys spot any errors in my design?
#synthesize textView = _textView;
#synthesize callbackViewController = _callbackViewController;
-(void)keyboardWasShown:(NSNotification*)aNotification {
if(keyboardShown) {
return;
}
NSDictionary *info = [aNotification userInfo];
// Get the size of the keyboard.
NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
keyboardSize = [aValue CGRectValue].size;
// Resize the scroll view (which is the root view of the window)
CGRect viewFrame = [self.textView frame];
orientationAtShown = orientation;
if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
viewFrame.size.height -= keyboardSize.height;
} else {
viewFrame.size.height -= keyboardSize.width;
}
self.textView.frame = viewFrame;
// Scroll the active text field into view.
//CGRect textFieldRect = [activeField frame];
[self.textView scrollRectToVisible:viewFrame animated:YES];
keyboardShown = YES;
}
-(void)keyboardWasHidden:(NSNotification*)aNotification {
if(!keyboardShown) {
return;
}
// Reset the height of the scroll view to its original value
CGRect viewFrame = [self.textView frame];
if(orientationAtShown == UIInterfaceOrientationPortrait || orientationAtShown == UIInterfaceOrientationPortraitUpsideDown) {
viewFrame.size.height += keyboardSize.height;
} else {
viewFrame.size.height += keyboardSize.width;
}
self.textView.frame = viewFrame;
keyboardShown = NO;
}
-(void)registerForKeyboardNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasHidden:)
name:UIKeyboardDidHideNotification object:nil];
}
-(void)viewWillAppear:(BOOL)animated {
keyboardShown = NO;
[self registerForKeyboardNotifications];
}
-(void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(keyboardShown) {
[self keyboardWasHidden:nil];
}
orientation = interfaceOrientation;
CGRect viewFrame = [self.textView frame];
if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
if(viewFrame.size.width > viewFrame.size.height) {
CGRect viewFrameFixed = CGRectMake(viewFrame.origin.x, viewFrame.origin.y, viewFrame.size.height, viewFrame.size.width);
self.textView.frame = viewFrameFixed;
}
} else {
if(viewFrame.size.width < viewFrame.size.height) {
CGRect viewFrameFixed = CGRectMake(viewFrame.origin.x, viewFrame.origin.y, viewFrame.size.height, viewFrame.size.width);
self.textView.frame = viewFrameFixed;
}
}
// Return YES for supported orientations
return YES;
}
#Alejandro above has the right idea, but his code does not work in landscape mode. I have amended his keyboardWasShown: method to work correctly in all orientations:
- (void)keyboardWasShown:(NSNotification *)notification {
if (self.textView != nil) {
NSDictionary* info = [notification userInfo];
CGRect keyboardRect = [self.textView convertRect:[[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil];
CGSize keyboardSize = keyboardRect.size;
self.textView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);
self.textView.scrollIndicatorInsets = self.textView.contentInset;
}
}
Add Observer first in viewDidLoad.
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
Call the methods
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
self.textView.contentInset = contentInsets;
self.textView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, self.textView.frame.origin) ) {
[self.textView scrollRectToVisible:self.textView.frame animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWasHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.textView.contentInset = contentInsets;
self.textView.scrollIndicatorInsets = contentInsets;
}
if you have more then 1 textfield or you want to reduce your code then try this code
- (void)textFieldDidBeginEditing:(UITextField *)textField{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35f];
CGRect frame = self.view.frame;
frame.origin.y = (self.view.frame.size.height - textField.frame.origin.y) - self.view.frame.size.height+60;
if (frame.origin.y<-162) {
frame.origin.y = -162;
}
[self.view setFrame:frame];
[UIView commitAnimations];
}
-(BOOL)textFieldShouldEndEditing:(UITextField *)textField{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35f];
CGRect frame = self.view.frame;
frame.origin.y = 0;
[self.view setFrame:frame];
[UIView commitAnimations];
return YES;
}
Extending #alejandro & #Mani :
Th final answer:
- (void)keyboardWasShown:(NSNotification *)notification {
if (self.textView != nil) {
NSDictionary* info = [notification userInfo];
CGRect keyboardRect = [self.textNote convertRect:[[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil];
CGSize keyboardSize = keyboardRect.size;
self.textView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);
self.textView.scrollIndicatorInsets = self.textView.contentInset;
}
}
- (void)keyboardWillBeHidden:(NSNotification*)notification {
self.textView.scrollIndicatorInsets = UIEdgeInsetsZero;
self.textView.scrollIndicatorInsets = UIEdgeInsetsZero;
}

Any good way to position UITableViewCellEditingStyleDelete icon within a grouped tableview?

as title, can i position the UITableViewCellEditingStyleDelete button/icon to be within the tableviewcell of a grouped tableview rather than outside of it?
An excerpt from a Matt Gallagher blog post reveals a method
This is the original code to mimic the behavior you DON'T want:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[self setNeedsLayout];
}
- (void)layoutSubviews
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[super layoutSubviews];
if (((UITableView *)self.superview).isEditing)
{
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = EDITING_HORIZONTAL_OFFSET;
self.contentView.frame = contentFrame;
}
else
{
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = 0;
self.contentView.frame = contentFrame;
}
[UIView commitAnimations];
}
So if we made a change, we can make it do what you do want:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[self setNeedsLayout];
}
- (void)layoutSubviews
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[super layoutSubviews];
if (((UITableView *)self.superview).isEditing)
{
//don't resize and and move your frame here
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = 0;
self.contentView.frame = contentFrame;
}
else
{
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = 0;
self.contentView.frame = contentFrame;
}
[UIView commitAnimations];
}
You'll proabably have to tweak this, but it is a good start.