-
Notifications
You must be signed in to change notification settings - Fork 0
/
FormViewController.m
130 lines (106 loc) · 3.96 KB
/
FormViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//
// FormViewController.m
//
// Provides UIScrollView for input fields and automatically scrolls to UITextField with focus. Also, dismisses the keyboard when the root UIView is tapped.
//
// Notes:
// You only need a nested UIView in the UIScrollView if the nested content will be taller than the scroll view itself. Make sure the scrollView refers to
// the UIScrollView instance
//
// Created by Brenden Soares on 11/15/13.
//
#import "FormViewController.h"
@interface FormViewController ()
@end
@implementation FormViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Watch for keyboard events
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShowWithObject:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHideWithObject:) name:UIKeyboardDidHideNotification object:nil];
// Dismisskeyboard on tap
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
tap.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tap];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewDidUnload {
self.scrollView = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidUnload];
}
#pragma mark - UITextField Delegate methods
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField.returnKeyType == UIReturnKeyNext) {
// Go to next field by view's tag
[[self.view viewWithTag:textField.tag+1] becomeFirstResponder];
} else if (textField.returnKeyType == UIReturnKeyDone) {
// Hide keyboard
[textField resignFirstResponder];
}
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
self.activeTextField = textField;
if (self.isKeyboardShowing)
{
[self scrollToField];
}
}
#pragma mark - Keyboard methods
- (void)keyboardDidShowWithObject: (NSNotification *)notification
{
self.isKeyboardShowing = YES;
NSDictionary *userInfo = [notification userInfo];
self.keyboardFrame = [[userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
[self scrollToField];
}
- (void)keyboardDidHideWithObject: (NSNotification *)notification
{
self.isKeyboardShowing = NO;
[self scrollToDefault];
}
-(void)dismissKeyboard
{
if (self.isKeyboardShowing) {
[self.activeTextField resignFirstResponder];
}
}
#pragma mark - UIScrollView methods
- (void)scrollToField
{
NSInteger scrollViewOffset = self.scrollView.contentOffset.y;
CGRect fieldFrame = self.activeTextField.frame;
CGRect areaCoveredByKeyboard = self.keyboardFrame;
// Convert to scrollView's coordinates
areaCoveredByKeyboard = [self.scrollView convertRect:areaCoveredByKeyboard fromView:nil];
// Calculate fields bottom coordinate
NSInteger fieldBottom = fieldFrame.origin.y + fieldFrame.size.height;
// Check if the field is being covered by the keyboard
if (areaCoveredByKeyboard.origin.y < fieldBottom)
{
NSInteger scrollToOffset = scrollViewOffset + fieldBottom - areaCoveredByKeyboard.origin.y;
// Add insets so we can scroll
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, scrollToOffset, 0.0);
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
// Scroll to active field
self.scrollView.contentOffset = CGPointMake(0, scrollViewOffset);
[self.scrollView setContentOffset:CGPointMake(0.0, scrollToOffset) animated:YES];
}
}
- (void)scrollToDefault
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
[self.scrollView setContentOffset:CGPointZero animated:YES];
}
@end