Reputation: 60923
I have a UITableView
that contains UITextField
in each cell
When I click UITextField
in the cell, the keyboard will show and cover my cell. Therefore, I move my cell to the top by using.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
CGPoint scrollPoint = CGPointMake(0, self.activeInputView.frame.origin.y);
[self.tableView setContentOffset:scrollPoint animated:YES];
}
If I use single click on each cell, my application work fine.
However, I use double click on each cell (it mean I tap on it 2 times very quickly), my cell will stop scroll to the top.
Upvotes: 5
Views: 549
Reputation: 16032
Here is a working example. You use your scroll view's contentInset and scrollIndicatorInsets properties to avoid the keyboard when it appears. You should register for keyboard notifications. Use the info in the notifications to determine the size of the keyboard--you never know what that will be.
Using content inset is the correct way to handle this for scroll views. If you subsequently need to scroll your editing row into view, use UITableView.scrollToRowAtIndexPath(_:, atScrollPosition:, animated:)
Notice that the does the right thing when the user hides/shows the completions bar.
import UIKit
import CoreGraphics
// our Cell class
class Cell : UITableViewCell
{
// cell reuse identifier for table view
static let Identifier = "Cell"
// the object the cell represents/displays. Could be anything you like
var value:AnyObject? {
didSet {
// update our text field when our cell value is set.
self.textField.text = value as? String
}
}
// use a text field to display our contents, since that allows editing and showing the keyboard
lazy var textField:UITextField = {
let textField = UITextField()
self.contentView.addSubview( textField )
return textField
}()
override func layoutSubviews() {
super.layoutSubviews()
self.textField.frame = contentView.bounds.insetBy(dx: 20, dy: 4 )
}
}
// table view data source class
class DataSource : NSObject, UITableViewDataSource
{
var numberOfRows:Int { return items.count }
let items = [ "Seoul", "São Paulo", "Bombay", "Jakarta", "Karachi", "Moskva", "Istanbul", "Mexico", "Shanghai", "Tokyo", "New" York, "Bangkok", "Beijing", "Delhi", "London", "Hong Kong", "Cairo", "Tehran", "Bogota", "Bandung", "Tianjin", "Lima", "Rio de Janeiro", "Lahore", "Bogor", "Santiago", "St Petersburg", "Shenyang", "Calcutta", "Wuhan" ]
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return numberOfRows
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier( Cell.Identifier ) as? Cell ?? Cell()
cell.value = items[ indexPath.row ]
return cell
}
}
class ViewController : UIViewController
{
override func viewDidLoad() {
super.viewDidLoad()
// register for notifications when the keyboard appears:
NSNotificationCenter.defaultCenter().addObserver( self, selector: "keyboardWillShow:", name: UIKeyboardWillChangeFrameNotification, object: nil)
}
override func viewDidLayoutSubviews() {
tableView.frame = view.bounds
}
lazy var tableView:UITableView = {
let tableView = UITableView()
self.view.addSubview( tableView )
tableView.dataSource = self.dataSource
tableView.delegate = self
return tableView
}()
lazy var dataSource : DataSource = DataSource()
// Handle keyboard frame changes here.
// Use the CGRect stored in the notification to determine what part of the screen the keyboard will cover.
// Adjust our table view's contentInset and scrollIndicatorInsets properties so that the table view content avoids the part of the screen covered by the keyboard
@objc func keyboardWillShow( note:NSNotification )
{
// read the CGRect from the notification (if any)
if let newFrame = (note.userInfo?[ UIKeyboardFrameEndUserInfoKey ] as? NSValue)?.CGRectValue() {
let insets = UIEdgeInsetsMake( 0, 0, newFrame.height, 0 )
tableView.contentInset = insets
tableView.scrollIndicatorInsets = insets
}
}
}
// need to conform to UITableViewDelegate protocol since we are the table view's delegate
extension ViewController : UITableViewDelegate
{
}
// App set up stuff here:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
lazy var window:UIWindow? = UIWindow()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window!.rootViewController = ViewController()
window!.makeKeyAndVisible()
return true
}
}
Upvotes: 0
Reputation: 13
Have you created separate UITableViewCell class ?
I believe as you scroll your UITableView your UI freezes or when you tab twice frequently your UITableView stops responding or taking time to respond.
Upvotes: 1
Reputation: 96
Are you sure that the scrollPoint is correct?
I just created a sample project with a fixed offset and everything works perfectly fine. The table view scrolls upwards after single and double tap on the UITextField
of a certain UITableViewCell
.
- (void)keyboardDidShow:(NSNotification *)notification {
CGPoint point = CGPointMake(0.0, 30.0);
[self.tableView setContentOffset:point animated:YES];
}
Upvotes: 2
Reputation: 224
In this line
CGPoint scrollPoint = CGPointMake(0, self.activeInputView.frame.origin.y);
can be 2 errors.
Firstly, you have to make sure that inputView that you have captured is the view you want. Secondly, you should convert fetched point to correct view using appropriate method.
See reference: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/doc/uid/TP40006816-CH3-SW52
For further investigation need more context.
Upvotes: 3
Reputation: 944
Try to use third party library IQKeyboardManager it will help you to solve this issue.
https://github.com/hackiftekhar/IQKeyboardManager
Replace following code in your AppDelegate.m file and then you don't need to use scrollview method to handle keyboard :-
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[IQKeyboardManager sharedManager] setEnable:YES];
[self.window makeKeyAndVisible];
return YES;
}
Upvotes: 1
Reputation: 313
rather then doing code for manually adjusting your tableview frame , Let me give you a suggestion, you can use IQKeyboardManager whose pod is available in cocoapods and it will manage of when clicking on cell's textfield , tableview will automatically scroll.
Upvotes: 2