Linh
Linh

Reputation: 60923

IOS Double click on cell cause item in UITableView won't scroll

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

Answers (7)

nielsbot
nielsbot

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

Viru1987
Viru1987

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

cherrmanncom
cherrmanncom

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

Alexander Orlov
Alexander Orlov

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

DJ1
DJ1

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

a_malika
a_malika

Reputation: 412

TPKeyboardAvoiding seems to be a solution.

Upvotes: 2

Vatsal Raval
Vatsal Raval

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

Related Questions