Add scroll to dismisskeyboard.

This commit is contained in:
Kyle Fang
2013-07-25 10:56:16 +08:00
parent 78f21227ff
commit 7bca2dbce2
6 changed files with 170 additions and 4 deletions

View File

@@ -34,10 +34,11 @@
//
#import <UIKit/UIKit.h>
#import "MADismissiveTextView.h"
@interface JSMessageInputView : UIImageView
@property (strong, nonatomic) UITextView *textView;
@property (strong, nonatomic) MADismissiveTextView *textView;
@property (strong, nonatomic) UIButton *sendButton;
#pragma mark - Initialization

View File

@@ -79,7 +79,7 @@
CGFloat width = self.frame.size.width - SEND_BUTTON_WIDTH;
CGFloat height = [JSMessageInputView textViewLineHeight];
self.textView = [[UITextView alloc] initWithFrame:CGRectMake(6.0f, 3.0f, width, height)];
self.textView = [[MADismissiveTextView alloc] initWithFrame:CGRectMake(6.0f, 3.0f, width, height)];
self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.textView.backgroundColor = [UIColor whiteColor];
self.textView.scrollIndicatorInsets = UIEdgeInsetsMake(10.0f, 0.0f, 10.0f, 8.0f);

View File

@@ -37,10 +37,11 @@
#import "NSString+JSMessagesView.h"
#import "UIView+AnimationOptionsForCurve.h"
#import "UIColor+JSMessagesView.h"
#import "MADismissiveTextView.h"
#define INPUT_HEIGHT 40.0f
@interface JSMessagesViewController ()
@interface JSMessagesViewController () <MADismissiveKeyboardDelegate>
- (void)setup;
@@ -71,7 +72,8 @@
CGRect inputFrame = CGRectMake(0.0f, size.height - INPUT_HEIGHT, size.width, INPUT_HEIGHT);
self.inputView = [[JSMessageInputView alloc] initWithFrame:inputFrame delegate:self];
self.inputView.textView.dismissivePanGestureRecognizer = self.tableView.panGestureRecognizer;
self.inputView.textView.keyboardDelegate = self;
UIButton *sendButton = [self sendButton];
sendButton.enabled = NO;
sendButton.frame = CGRectMake(self.inputView.frame.size.width - 65.0f, 8.0f, 59.0f, 26.0f);
@@ -87,6 +89,14 @@
[self.inputView addGestureRecognizer:swipe];
}
- (void)keyboardDidScroll:(CGPoint)keyboardOrigin{
CGRect inputViewFrame = self.inputView.frame;
inputViewFrame.origin.y = keyboardOrigin.y - 266 + 160;
self.inputView.frame = inputViewFrame;
NSLog(@"%g --- %g", keyboardOrigin.y, inputViewFrame.origin.y);
}
- (UIButton *)sendButton
{
return [UIButton defaultSendButton];

View File

@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
04E5799317A0B25E0022CD77 /* MADismissiveTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04E5799217A0B25E0022CD77 /* MADismissiveTextView.m */; };
881AE55D16D13CDC008F7636 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 881AE55C16D13CDC008F7636 /* UIKit.framework */; };
881AE55F16D13CDC008F7636 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 881AE55E16D13CDC008F7636 /* Foundation.framework */; };
881AE56116D13CDC008F7636 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 881AE56016D13CDC008F7636 /* CoreGraphics.framework */; };
@@ -54,6 +55,8 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
04E5799117A0B25E0022CD77 /* MADismissiveTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MADismissiveTextView.h; sourceTree = "<group>"; };
04E5799217A0B25E0022CD77 /* MADismissiveTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MADismissiveTextView.m; sourceTree = "<group>"; };
881AE55916D13CDC008F7636 /* MessagesDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MessagesDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
881AE55C16D13CDC008F7636 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
881AE55E16D13CDC008F7636 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
@@ -160,6 +163,8 @@
881AE56216D13CDC008F7636 /* MessagesDemo */ = {
isa = PBXGroup;
children = (
04E5799117A0B25E0022CD77 /* MADismissiveTextView.h */,
04E5799217A0B25E0022CD77 /* MADismissiveTextView.m */,
881AE56B16D13CDC008F7636 /* AppDelegate.h */,
881AE56C16D13CDC008F7636 /* AppDelegate.m */,
881AE58216D13DE0008F7636 /* DemoViewController.h */,
@@ -359,6 +364,7 @@
88301F2016F77B3D0037524D /* UIView+AnimationOptionsForCurve.m in Sources */,
8856C7DD16F9273C00FC921C /* UIColor+JSMessagesView.m in Sources */,
88E5341F16FF9B02004272FA /* UIButton+JSMessagesView.m in Sources */,
04E5799317A0B25E0022CD77 /* MADismissiveTextView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -0,0 +1,25 @@
//
// MADismissiveTextView.h
// MADismissiveTextView
//
// Created by Mike Ahmarani on 12-02-18.
// Copyright (c) 2012 Mike Ahmarani. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol MADismissiveKeyboardDelegate <NSObject>
@optional
- (void)keyboardDidShow;
- (void)keyboardDidScroll:(CGPoint)keyboardOrigin;
- (void)keyboardWillBeDismissed;
- (void)keyboardWillSnapBack;
@end
@interface MADismissiveTextView : UITextView
@property (nonatomic, weak) id <MADismissiveKeyboardDelegate> keyboardDelegate;
@property (nonatomic, strong) UIPanGestureRecognizer *dismissivePanGestureRecognizer;
@end

View File

@@ -0,0 +1,124 @@
//
// MADismissiveTextView.m
// MADismissiveTextView
//
// Created by Mike Ahmarani on 12-02-18.
// Copyright (c) 2012 Mike Ahmarani. All rights reserved.
//
#import "MADismissiveTextView.h"
@interface MADismissiveTextView ()
@property (nonatomic, strong) UIView *keyboard;
@property (nonatomic, readwrite) float originalKeyboardY;
- (void)keyboardWillShow;
- (void)keyboardDidShow;
- (void)panning:(UIPanGestureRecognizer *)pan;
@end
@implementation MADismissiveTextView
@synthesize keyboard, dismissivePanGestureRecognizer, originalKeyboardY, keyboardDelegate;
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.dismissivePanGestureRecognizer removeTarget:self action:@selector(panning:)];
self.dismissivePanGestureRecognizer = nil;
self.keyboardDelegate = nil;
}
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.editable = YES;
self.inputAccessoryView = [[UIView alloc] init]; //Empty view, used to get a handle on the keyboard when it appears.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow) name:@"UIKeyboardWillShowNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow) name:@"UIKeyboardDidShowNotification" object:nil];
}
return self;
}
- (void)setDismissivePanGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecognizer{
dismissivePanGestureRecognizer = panGestureRecognizer;
[dismissivePanGestureRecognizer addTarget:self action:@selector(panning:)];
}
- (void)keyboardWillShow{
self.keyboard.hidden = NO;
}
- (void)keyboardDidShow{
self.keyboard = self.inputAccessoryView.superview;
if(self.keyboardDelegate && [self.keyboardDelegate respondsToSelector:@selector(keyboardDidShow)]){
[self.keyboardDelegate keyboardDidShow];
}
}
- (void)panning:(UIPanGestureRecognizer *)pan{
if(self.keyboard && !self.keyboard.hidden){
UIWindow *panWindow = [[UIApplication sharedApplication] keyWindow];
CGPoint location = [pan locationInView:panWindow];
CGPoint velocity = [pan velocityInView:panWindow];
if(pan.state == UIGestureRecognizerStateBegan){ //Gesture begining, grab origin of keyboard frame.
self.originalKeyboardY = self.keyboard.frame.origin.y;
}else if(pan.state == UIGestureRecognizerStateEnded){ //Gesture ending, complete animation of keyboard
if(velocity.y > 0 && self.keyboard.frame.origin.y > self.originalKeyboardY){ //Gesture ended with a flick downwards, dismiss keyboard.
if(self.keyboardDelegate && [self.keyboardDelegate respondsToSelector:@selector(keyboardWillBeDismissed)]){
[self.keyboardDelegate keyboardWillBeDismissed];
}
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.keyboard.frame = CGRectMake(0, 480, self.keyboard.frame.size.width, self.keyboard.frame.size.height);
}completion:^(BOOL finished){
self.keyboard.hidden = YES;
self.keyboard.frame = CGRectMake(0, self.originalKeyboardY, self.keyboard.frame.size.width, self.keyboard.frame.size.height);
[self resignFirstResponder];
}];
}else{ //Gesture ended with no flick or a flick upwards, snap keyboard back to original position.
if(self.keyboardDelegate && [self.keyboardDelegate respondsToSelector:@selector(keyboardWillSnapBack)]){
[self.keyboardDelegate keyboardWillSnapBack];
}
[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.keyboard.frame = CGRectMake(0, self.originalKeyboardY, self.keyboard.frame.size.width, self.keyboard.frame.size.height);
} completion:^(BOOL finished){
}];
}
}else{ //Gesture is currently panning, match keyboard y to touch y.
if(location.y > self.keyboard.frame.origin.y || self.keyboard.frame.origin.y != self.originalKeyboardY){
float newKeyboardY = self.originalKeyboardY + (location.y-self.originalKeyboardY);
newKeyboardY = newKeyboardY < self.originalKeyboardY ? self.originalKeyboardY:newKeyboardY;
newKeyboardY = newKeyboardY > 480 ? 480:newKeyboardY;
self.keyboard.frame = CGRectMake(0, newKeyboardY, self.keyboard.frame.size.width, self.keyboard.frame.size.height);
if(self.keyboardDelegate && [self.keyboardDelegate respondsToSelector:@selector(keyboardDidScroll:)]){
[self.keyboardDelegate keyboardDidScroll:CGPointMake(0, newKeyboardY)];
}
}
}
}
}
@end