Custom Segue not allowing IBActions in destination controller - animation

I have two View Controllers with views. The first one is a login screen and the second one fetches stuff from the web (irrelevant).
I used a custom segue animation and had to do some weird stuff with the superview to get the sourceViewController.view to be "on top" (visually) of the destinationViewController.view
I can only assume this is why when i try to call IBAction methods from the second view they won't call.
Here is the segue class implementation:
- (void) perform {
UIViewController *sourceViewController = (UIViewController *) self.sourceViewController;
UIViewController *destinationViewController = (UIViewController *) self.destinationViewController;
UIView *parent = sourceViewController.view.superview;
[sourceViewController.view removeFromSuperview];
[parent addSubview: destinationViewController.view];
[parent addSubview:sourceViewController.view];
sourceViewController.view.layer.masksToBounds = NO;
sourceViewController.view.layer.cornerRadius = 8; // if you like rounded corners
sourceViewController.view.layer.shadowOffset = CGSizeMake(0,0);
sourceViewController.view.layer.shadowRadius = 10;
sourceViewController.view.layer.shadowOpacity = 1;
destinationViewController.view.frame = CGRectMake(0, 20, destinationViewController.view.frame.size.width, destinationViewController.view.frame.size.height);
sourceViewController.view.frame = CGRectMake(0, 20, sourceViewController.view.frame.size.width, sourceViewController.view.frame.size.height);
[UIView animateWithDuration:.6
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^{
sourceViewController.view.frame = CGRectMake(-sourceViewController.view.frame.size.width-10, 20, sourceViewController.view.frame.size.width, sourceViewController.view.frame.size.height);
}
completion:^(BOOL finished){
//[destinationViewController.view removeFromSuperview];
[sourceViewController.navigationController pushViewController:destinationViewController animated:NO];
}];
}
My question is, can removing the source view from its superview and playing around with that ruin the way that IBActions are called on the second view?
The IBAction methods just crash the app, on a button push for example.

I fixed my issue by changing my code to this:
UIViewController *sourceViewController = (UIViewController *) self.sourceViewController;
UIViewController *destinationViewController = (UIViewController *) self.destinationViewController;
UIView *parent = sourceViewController.view.superview;
[parent addSubview:destinationViewController.view];
[parent sendSubviewToBack: destinationViewController.view];
sourceViewController.view.layer.masksToBounds = NO;
sourceViewController.view.layer.cornerRadius = 8; // if you like rounded corners
sourceViewController.view.layer.shadowOffset = CGSizeMake(0,0);
sourceViewController.view.layer.shadowRadius = 10;
sourceViewController.view.layer.shadowOpacity = 1;
destinationViewController.view.frame = CGRectMake(0, 20, destinationViewController.view.frame.size.width, destinationViewController.view.frame.size.height);
sourceViewController.view.frame = CGRectMake(0, 20, sourceViewController.view.frame.size.width, sourceViewController.view.frame.size.height);
[UIView animateWithDuration:.6
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^{
sourceViewController.view.frame = CGRectMake(-sourceViewController.view.frame.size.width-10, 20, sourceViewController.view.frame.size.width, sourceViewController.view.frame.size.height);
}
completion:^(BOOL finished){
[sourceViewController presentViewController:destinationViewController animated:NO completion:NULL];
}];
A few things changed, but notably, i used
[sourceViewController presentViewController:destinationViewController animated:NO completion:NULL];
to initialise the controller properly.
Hope this helps someone else out in the future.

Related

How do I implement frameForAlignmentRect:/alignmentRectForFrame: such that the frame outside the alignment rect encapsulates those of subviews?

So I now have my Auto Layout-based container working, for the most part. On 10.8 (I need to run on 10.7 and newer), I see this:
Notice how the sides of the NSProgressIndicator and NSPopUpButton are clipped.
After some experimentation, I found that overriding alignmentRectInsets and returning 50 pixels of insets on all sides shows no clipping:
In both cases, the controls are bound to the left and right edges of the container view alignment rect with H:|[view]|. I imagine this will happen on other versions of OS X too, but it's most noticeable here (and as of writing I only have access to 10.8 and 10.10 installs).
Now, using alignment rect insets of 50 pixels on each side sounds wrong. I don't think there'd be any control that would need more than 50 pixels, but I'd rather do these correctly. So my question is: How do I implement the alignmentRectForFrame: and frameForAlignmentRect: selectors to properly account for the frames and alignment rects of the subviews?
Right now, I'm thinking to force a layout and then observe the frames and alignment rects of each subview, assuming that alignment rect (0, 0) of my last subview (the subviews are arranged linearly) will be at alignment rect (0, 0) of the container view. But I'm not sure if this approach is sufficient to handle all cases, and I'm not sure if I can invert the operation in the same way that these two selectors require. Subtraction, maybe?
If what I described above is the solution, could I do that with alignmentRectInsets, or must the insets returned by that method never change during the lifetime of the view?
Or is the second screenshot showing a scenario that Interface Builder won't reproduce, and thus I assume is "wrong" from a guidelines standpoint?
In the sample program below, start without a command-line argument to simulate the first screenshot, and start with an argument to simulate the second screenshot. Check the Spaced checkbox to add spacing to the views.
Thanks!
// 17 august 2015
#import <Cocoa/Cocoa.h>
BOOL useInsets = NO;
#interface ContainerView : NSView
#end
#implementation ContainerView
- (NSEdgeInsets)alignmentRectInsets
{
if (useInsets)
return NSEdgeInsetsMake(50, 50, 50, 50);
return [super alignmentRectInsets];
}
#end
NSWindow *mainwin;
NSView *containerView;
NSProgressIndicator *progressbar;
NSPopUpButton *popupbutton;
NSButton *checkbox;
void addConstraints(NSView *view, NSString *constraint, NSDictionary *views)
{
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:constraint
options:0
metrics:nil
views:views];
[view addConstraints:constraints];
}
void relayout(BOOL spaced)
{
[containerView removeConstraints:[containerView constraints]];
NSDictionary *views = #{
#"pbar": progressbar,
#"pbutton": popupbutton,
#"checkbox": checkbox,
};
NSString *vconstraint = #"V:|[pbar][pbutton][checkbox]|";
if (spaced)
vconstraint = #"V:|[pbar]-[pbutton]-[checkbox]|";
addConstraints(containerView, vconstraint, views);
addConstraints(containerView, #"H:|[pbar]|", views);
addConstraints(containerView, #"H:|[pbutton]|", views);
addConstraints(containerView, #"H:|[checkbox]|", views);
NSView *contentView = [mainwin contentView];
[contentView removeConstraints:[contentView constraints]];
NSString *base = #":|[view]|";
if (spaced)
base = #":|-[view]-|";
views = #{
#"view": containerView,
};
addConstraints(contentView, [#"H" stringByAppendingString:base], views);
addConstraints(contentView, [#"V" stringByAppendingString:base], views);
}
#interface appDelegate : NSObject<NSApplicationDelegate>
#end
#implementation appDelegate
- (IBAction)onChecked:(id)sender
{
relayout([checkbox state] == NSOnState);
}
- (void)applicationDidFinishLaunching:(NSNotification *)note
{
mainwin = [[NSWindow alloc]
initWithContentRect:NSMakeRect(0, 0, 320, 240)
styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)
backing:NSBackingStoreBuffered
defer:YES];
NSView *contentView = [mainwin contentView];
containerView = [[ContainerView alloc] initWithFrame:NSZeroRect];
[containerView setTranslatesAutoresizingMaskIntoConstraints:NO];
progressbar = [[NSProgressIndicator alloc] initWithFrame:NSZeroRect];
[progressbar setControlSize:NSRegularControlSize];
[progressbar setBezeled:YES];
[progressbar setStyle:NSProgressIndicatorBarStyle];
[progressbar setIndeterminate:NO];
[progressbar setTranslatesAutoresizingMaskIntoConstraints:NO];
[containerView addSubview:progressbar];
popupbutton = [[NSPopUpButton alloc] initWithFrame:NSZeroRect];
[popupbutton setPreferredEdge:NSMinYEdge];
NSPopUpButtonCell *pbcell = (NSPopUpButtonCell *) [popupbutton cell];
[pbcell setArrowPosition:NSPopUpArrowAtBottom];
[popupbutton addItemWithTitle:#"Item 1"];
[popupbutton addItemWithTitle:#"Item 2"];
[popupbutton setTranslatesAutoresizingMaskIntoConstraints:NO];
[containerView addSubview:popupbutton];
checkbox = [[NSButton alloc] initWithFrame:NSZeroRect];
[checkbox setTitle:#"Spaced"];
[checkbox setButtonType:NSSwitchButton];
[checkbox setBordered:NO];
[checkbox setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
[checkbox setTarget:self];
[checkbox setAction:#selector(onChecked:)];
[checkbox setTranslatesAutoresizingMaskIntoConstraints:NO];
[containerView addSubview:checkbox];
[contentView addSubview:containerView];
relayout(NO);
[mainwin cascadeTopLeftFromPoint:NSMakePoint(20, 20)];
[mainwin makeKeyAndOrderFront:mainwin];
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app
{
return YES;
}
#end
int main(int argc, char *argv[])
{
useInsets = (argc > 1);
NSApplication *app = [NSApplication sharedApplication];
[app setActivationPolicy:NSApplicationActivationPolicyRegular];
[app setDelegate:[appDelegate new]];
[app run];
return 0;
}

Getting a CollectionView delegate to load properly

(Let me first put the error up here so that I don't forget it: could not dequeue a view of kind: UICollectionElementKindCell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard)
I've got a regular UICollectionViewController that loads just fine. But I also have another controller (UserViewController) that loads a CollectionView delegate (UserPlaceViewController).
I get really confused with what I have to load in the delegate and what I have to load in the current controller. But anyway here's the delegate as-is:
#import "UserPlaceViewController.h"
#interface UserPlaceViewController ()
#end
#implementation UserPlaceViewController
#synthesize placeArray, placeTable;
- (void)viewDidLoad
{
[super viewDidLoad];
// placeTable.delegate = self;
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(145, 150);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
placeTable = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
//self.collectionView.frame = CGRectMake(10, 120, self.view.bounds.size.width-20, self.view.bounds.size.height-50);
placeTable.autoresizesSubviews = YES;
placeTable.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
//placeTable.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
placeTable.scrollEnabled = YES;
self.view = placeTable;
NSLog(#"%lu", (unsigned long)[placeArray count]);
}
That's basically the whole thing. Couple other things at the end... but that's it for the most part.
And here are the relevent parts of the ViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES animated:YES];
UserPlaceViewController *collectionView = [[UserPlaceViewController alloc] initWithNibName:#"UserPlace" bundle:nil];
UINib * placeCell = [UINib nibWithNibName:#"Shops" bundle:nil];
[collectionView.placeTable registerNib:placeCell forCellWithReuseIdentifier:cellIdentifier];
- (void) fetchedData: (NSData *) responseData
{
UserPlaceViewController * uptvLike = [[UserPlaceViewController alloc] init];
if (IS_IPHONE5) {
uptvLike.view.frame = CGRectMake(0, 0, 320, 300);
}
else
{
uptvLike.view.frame = CGRectMake(0, 0, 320, 200);
}
uptvLike.placeTable.delegate = self;
uptvLike.placeTable.dataSource = self;
uptvLike.placeTable.layer.borderWidth = 1.0f;
uptvLike.placeTable.layer.borderColor = [UIColor colorWithRed:5/255.0f green:96/255.0f blue:255/255.0f alpha:1.0f].CGColor;
[uptvLike.placeTable reloadData];
[self.scrollView addSubview:uptvLike.view];
}
And finally:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PlaceCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
Place * p = [placeArray objectAtIndex:indexPath.item];
cell.placeName.text = p.PName;
cell.placeImg.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:p.PImage]]];
return cell;
}
Like I said: I know how a UICollectionView is supposed to work. I've got one running. I know you have to register a nib or class in viewDidLoad (I've registered a Nib.) But I'm confused over how exactly to load this delegate and where to load what. For example I see that I'm initialising the collectionview in both the delegate and the view controller. I'm also confused about WHERE exactly I should load the nib... (delegates give me a headache...)
So what the hell... It's raining. I figured I'd ask.
Ok. You want a UICollectionView but you also want to have a lot of regular "View" items on the same screen? Two things are important:
1. You don't need two ViewControllers. You just need to load what would normally be your UICollectionViewController as a regular ViewController:
#interface UserViewController : UIViewController <UICollectionViewDataSource, UIScrollViewDelegate>
2. Once that's done you can load your collectionview on TOP of that view:
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(145, 150);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout];
[self.scrollView addSubview:self.collectionView];
[self.view addSubview:HUD];
UINib * placeCell = [UINib nibWithNibName:#"UserCell" bundle:nil];
[self.collectionView registerNib:placeCell forCellWithReuseIdentifier:#"Cell"];
The rest is just your standard CollectionView stuff.

Issue with UITabBar button, TabBar button becomes un clickable

I am creating a view with UINavigationBar and UITabBar. I have added a button on tab bar, on button click, i am hiding tab bar and show tool bar at the bottom. My code is written for current as well as previous iOS versions. I am using this code self.edgesForExtendedLayout = UIRectEdgeNone; for iOS7 this is my code :
- (void)hideTabBar {
UITabBar *tabBar = self.tabBarController.tabBar;
UIView *parent = tabBar.superview; // UILayoutContainerView
UIView *content = [parent.subviews objectAtIndex:0]; // UITransitionView
UIView *window = parent.superview;enter code here
[UIView animateWithDuration:0.5
animations:^{
CGRect tabFrame = tabBar.frame;
tabFrame.origin.y = CGRectGetMaxY(window.bounds);
tabBar.frame = tabFrame;
// CGRect contentFrame = content.frame;
// contentFrame.size.height -= tabFrame.size.height;
content.frame = window.bounds;
}];
if ([[[UIDevice currentDevice] systemVersion] intValue] < 7.0)
{
CGRect frame = tbl_AllFiles.frame;
frame.size.height -=tabBar.frame.size.height;
tbl_AllFiles.frame = frame;
}
}
- (void)showTabBar {
UITabBar *tabBar = self.tabBarController.tabBar;
UIView *parent = tabBar.superview; // UILayoutContainerView
UIView *content = [parent.subviews objectAtIndex:0]; // UITransitionView
UIView *window = parent.superview;
if ([[[UIDevice currentDevice] systemVersion] intValue] < 7.0)
{
CGRect frame = tbl_AllFiles.frame;
frame.size.height +=tabBar.frame.size.height;
tbl_AllFiles.frame = frame;
}
[UIView animateWithDuration:0.5
animations:^{
CGRect tabFrame = tabBar.frame;
tabFrame.origin.y = CGRectGetMaxY(window.bounds) - CGRectGetHeight(tabBar.frame);
tabBar.frame = tabFrame;
CGRect contentFrame = content.frame;
contentFrame.size.height -= tabFrame.size.height;
content.frame = contentFrame;
}];
}
- (void)loadToolBar {
toolbar = [UIToolbar new];
toolbar.barStyle = UIBarStyleBlackTranslucent;
moveButton = [UIButton buttonWithType:UIButtonTypeCustom];
[moveButton setFrame:CGRectMake(10, 10, 120, 25)];
[moveButton setBackgroundColor:[UIColor redColor]];
[moveButton setTitle:#"Move" forState:UIControlStateNormal];
[moveButton addTarget:self action:#selector(moveFile_Folder:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *moveItem = [[[UIBarButtonItem alloc] initWithCustomView:moveButton] autorelease];
moveItem.style = UIBarButtonItemStyleBordered;
NSArray *items = [NSArray arrayWithObjects:moveItem, nil];
toolbar.items = items;
[toolbar sizeToFit];
CGFloat toolbarHeight = [toolbar frame].size.height;
CGRect mainViewBounds = self.view.bounds;
if ([[[UIDevice currentDevice] systemVersion] intValue] < 7.0)
{
[toolbar setFrame:CGRectMake(CGRectGetMinX(mainViewBounds),
CGRectGetMinY(mainViewBounds) + CGRectGetHeight(mainViewBounds) - (toolbarHeight),
CGRectGetWidth(mainViewBounds),
toolbarHeight)];
}
else
{
[toolbar setFrame:CGRectMake(CGRectGetMinX(mainViewBounds),
CGRectGetMinY(mainViewBounds) + CGRectGetHeight(mainViewBounds),
CGRectGetWidth(mainViewBounds),
toolbarHeight)];
}
[self.view addSubview:toolbar];
[toolbar bringSubviewToFront:self.view];
}
My issue is on button clicked hideTabBar and loadToolBar methods are called. Everything is working fine, except my button is un-clickable now on toolbar.
Please help me.
i had a similar issue if your viewcontroller is not the root view controller iOS doesn't get the view frame.
Add this line to your viewcontroller in viewdidload,
self.view.frame = [UIScreen mainScreen].bounds;
hope it helps

how can I make a scrollView autoscroll?

I have this scrollView:
self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.scrollView.contentSize = CGSizeMake(320,3000);
_scrollView.frame = CGRectMake(0, 45, 320, 420);
and I want to make it autoscroll very slowly downward to the end so that the user can see the content (as in movie credits), eventually with a button to stop/play, but to follow the user gestures when touching the interface.
How can I do this?
Thanks,
You can use:
[_scrollView setContentOffset:CGPointMake(x,y) animated:YES];
and use the x and y as the touch points on the screen you can capture.
You can also do an animation with CoreAnimation:
[UIScrollView beginAnimations:#"scrollAnimation" context:nil];
[UIScrollView setAnimationDuration:1.0f];
[scroll setContentOffset:CGPointMake(x, y)];
[UIScrollView commitAnimations];
this adapted code did the trick (source http://sugartin.info/2012/01/21/image-sliding-page-by-page-uiscrollview-auto-scrolling-like-image-slider/)
PS : each image is 280 by 200
- (void)viewDidLoad
{
[super viewDidLoad];
UIScrollView *scr=[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scr.tag = 1;
scr.autoresizingMask=UIViewAutoresizingNone;
[self.view addSubview:scr];
[self setupScrollView:scr];
UIPageControl *pgCtr = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 264, 480, 36)];
[pgCtr setTag:12];
pgCtr.numberOfPages=10;
pgCtr.autoresizingMask=UIViewAutoresizingNone;
[self.view addSubview:pgCtr];
}
- (void)setupScrollView:(UIScrollView*)scrMain {
// we have 10 images here.
// we will add all images into a scrollView & set the appropriate size.
for (int i=1; i<=10; i++) {
// create image
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"sti%02i.jpg",i]];
// create imageView
UIImageView *imgV = [[UIImageView alloc] initWithFrame:CGRectMake(20, ((i-1)*scrMain.frame.size.height+100), 280, 200)];
// set scale to fill
imgV.contentMode=UIViewContentModeScaleToFill;
// set image
[imgV setImage:image];
// apply tag to access in future
imgV.tag=i+1;
// add to scrollView
[scrMain addSubview:imgV];
}
// set the content size to 10 image width
[scrMain setContentSize:CGSizeMake(scrMain.frame.size.width, scrMain.frame.size.height*10)];
// enable timer after each 2 seconds for scrolling.
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(scrollingTimer) userInfo:nil repeats:YES];
}
- (void)scrollingTimer {
// access the scroll view with the tag
UIScrollView *scrMain = (UIScrollView*) [self.view viewWithTag:1];
// same way, access pagecontroll access
UIPageControl *pgCtr = (UIPageControl*) [self.view viewWithTag:12];
// get the current offset ( which page is being displayed )
CGFloat contentOffset = scrMain.contentOffset.y;
// calculate next page to display
int nextPage = (int)(contentOffset/scrMain.frame.size.height) + 1 ;
// if page is not 10, display it
if( nextPage!=10 ) {
[scrMain scrollRectToVisible:CGRectMake(0, nextPage*scrMain.frame.size.height, scrMain.frame.size.width, scrMain.frame.size.height) animated:YES];
pgCtr.currentPage=nextPage;
// else start sliding form 1 :)
} else {
[scrMain scrollRectToVisible:CGRectMake(0, 0, scrMain.frame.size.width, scrMain.frame.size.height) animated:YES];
pgCtr.currentPage=0;
}
}
You can set x if you want to scroll horizontally, otherwise set y to scroll vertical.
[_scrollView setContentOffset:CGPointMake(x, y) animated:YES];
and modify the co-ordinates accordingly.

Keyboard behavior when forced open with inputAccessoryView?

I have a device connected to my iPad that is acting as an external keyboard, however, I still need a soft keyboard in my program. I have had some luck using the following article: Show iphone soft keyboard even thought a hardware keyboard is connected, but iOS 5 has broken this method. The bottom of the soft keyboard is slightly cut off in most views, but others only half the keyboard appears inside the window and not where you would expect it to.
All of the following code works in my AppDelegate.m file in iOS4, but not in iOS5.
forceKeyboard is called after UITextFieldTextDidBeginEditingNotification is sent.
-(void) textFieldBegan: (NSNotification *) theNotification
{
UITextField *theTextField = [theNotification object];
theTextField.inputAccessoryView = inputAccessoryView;
[self performSelector:#selector(forceKeyboard) withObject:nil afterDelay:0];
}
//Change the inputAccessoryView frame
-(void) forceKeyboard
{
inputAccessoryView.superview.frame = CGRectMake(0, 502, 1024, 265);
int movementDistance = 1;
float movementDuration = 0.3f;
[UIView beginAnimations: #"kb_anim_open" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
inputAccessoryView.superview.frame = CGRectOffset(inputAccessoryView.superview.frame, 0, movementDistance);
[UIView commitAnimations];
}
Close Keyboard is called after UITextFieldTextDidEndEditingNotification is sent.
-(void) textFieldEnd: (NSNotification *) theNotification
{
UITextView *theTextView = [theNotification object];
[theTextView resignFirstResponder];
[self performSelector:#selector(forceCloseKeyboard) withObject:nil afterDelay:0];
}
-(void) forceCloseKeyboard
{
inputAccessoryView.superview.frame = CGRectMake(0, 502, 1024, 265);
int movementDistance = 502;
float movementDuration = 0.3f;
[UIView beginAnimations: #"kb_anim_close" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
inputAccessoryView.superview.frame = CGRectOffset(inputAccessoryView.superview.frame, 0, movementDistance);
[UIView commitAnimations];
}
Any ideas on how I can tame a soft keyboard would be greatly appreciated; I've tried wrestling with the superview.frame values for awhile but with no luck.
Thanks for reading.
UPDATE
I have figured out a setup that opens and closes the keyboard in iOS 4 and 5, but does not animate. Again, this is all in the AppDelegate where "textFieldBegan" and "textFieldEnd" are called by notifications sent when a user begins and ends editing respectively.
-(void) textFieldBegan: (NSNotification *) theNotification
{
UITextField *theTextField = [theNotification object];
if (!inputAccessoryView) {
inputAccessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 1)];
}else{
inputAccessoryView.frame = CGRectMake(0, 0, 1024, 1);
}
theTextField.inputAccessoryView = inputAccessoryView;
[self performSelector:#selector(forceKeyboard) withObject:nil afterDelay:0];
}
-(void) textFieldEnd: (NSNotification *) theNotification
{
NSString *classstr = NSStringFromClass([[theNotification object] class]);
UITextView *theTextView = [theNotification object];
[self performSelector:#selector(forceCloseKeyboard) withObject:nil afterDelay:0];
[theTextView resignFirstResponder];
}
//Change the inputAccessoryView frame
-(void) forceKeyboard
{
//default center = 512, 591
inputAccessoryView.superview.frame = CGRectMake(0, 415, 1024, 353);
[UIView animateWithDuration:0.3 animations: ^ { [inputAccessoryView.superview transform]; }];
}
-(void) forceCloseKeyboard //Unnecessary?
{
inputAccessoryView.frame = CGRectMake(0, 0, 1024, 0);
[UIView animateWithDuration:0.3 animations: ^ { [inputAccessoryView transform]; }];
}
It looks as if the "forceCloseKeyboard" method isn't really doing anything as it looks like when the textField resigns responder it closes the keyboard anyway. I leave it here in case someone can come up with a way to animate the keyboard opening and closing.

Resources